Linuxのgdbに対してプログラムでCまたはC ++コードにブレークポイントを設定する


104

Linuxのgdbで機能するように、プログラムでCまたはC ++コードにブレークポイントを設定するにはどうすればよいですか?

すなわち:

int main(int argc, char** argv)
{
    /* set breakpoint here! */
    int a = 3;
    a++;  /*  In gdb> print a;  expect result to be 3 */
    return 0;
}

8
非常に多くのサイドノート(申し訳ありませんnitpickに)していますが、その後、移植性を心配している場合、あなたはおそらくも正しさを心配している-それゆえint mainではなくvoid main
Stuart Golodetz、2010

@Stuart-修正されました。少し前にそれをするべきでした。
J. Polfer、2011年

4
@ J.Polfer:return 0必要はありませんが、ノイズです。
オービットのライトネスレース

回答:


106

1つの方法は、割り込みを通知することです。

#include <csignal>

// Generate an interrupt
std::raise(SIGINT);

C:

#include <signal.h>
raise(SIGINT);

更新MSDNでは、Windowsは実際にはをサポートしていないSIGINTため、移植性が懸念される場合は、を使用しSIGABRTた方がよいでしょう。


はい、これはオペレーティングシステム/コンパイラ/デバッガで機能するはずです。
HåvardS

1
他のデバッガーは知りませんが、gdbはシグナル処理に関してかなり柔軟です。
Cascabel、2010

4
我々はいくつかのUnix上で、より良いSIGTRAPを発見した
JBRWilkinson

1
Windows、MSVCでは、__ debug_break、DebugBreak、または_asm {int 3}を使用できます。
フェルナンドゴンザレスサンチェス

2
@FernandoGonzalezSanchez:ここに表示されているように、実際には関数名はで__debugbreak()あり、NOT です__debug_break()
Morix Dev

27

私が取り組んでいるプロジェクトでは、これを行います:

raise(SIGABRT);  /* To continue from here in GDB: "signal 0". */

(私たちのケースでは、これがデバッガの外で発生した場合、ハードクラッシュして、可能であればクラッシュレポートを生成します。これがSIGABRTを使用した理由の1つです。これをWindows、Mac、Linux間で移植して実行するには、いくつかの試みが必要でした。 #ifdefs、参考になったコメント:http : //hg.mozilla.org/mozilla-central/file/98fa9c0cff7a/js/src/jsutil.cpp#l66


2
いつものように、ウィンドウは他のウィンドウのようには見えません:)
mathk '29

「シグナル0」を発行して、一時停止した状態でプログラムのプログラムを続行できますか?この時点から、「c」を発行せずに「n」または「s」を使用できると便利です。
Jason Doucette 2016

2
@JasonDoucette本当にプログラムを一時停止するだけの場合は、プログラムにbreakpoint()関数を追加して(空にすることも、単にprintステートメントを含めることもできます)、に追加するbreak breakpointこともできます~/.gdbinit
Jason Orendorff 2016

26

ここを見、私は次の方法を見つけました:

void main(int argc, char** argv)
{
    asm("int $3");
    int a = 3;
    a++;  //  In gdb> print a;  expect result to be 3
}

これはちょっとハックらしいです。そして、これはx86アーキテクチャでのみ機能すると思います。


3
そして、AT&Tアセンブリ構文をサポートするコンパイラのみ。特に、Microsoftのコンパイラ(cl.exe)はこの構文をサポートしていませんが、別の構文を使用しています。
HåvardS

質問はLinuxに関するものだったので、x86でgcc構文が機能すると想定できます。
js。

ところで-私は私のx86マシンで上記を試してみましたが、うまくいきました。もっと良い方法があるかどうか気になりました。あるように見えます。
J. Polfer、2010

2
私はウィンドウでmingwを使用しているので、他の提案は私を助けることができません。SIGINTシグナルを発生させるとアプリケーションが終了するだけで、SIGTRAPはmingwヘッダーに定義されていません... int命令を使用すると、実際にSIGTRAPが送信され、適切な行でgdbが適切に中断します。
マハタ2014年

Linuxではint 3、SIGTRAPを発生させます。
Ciro Santilli郝海东冠状病六四事件法轮功

11

__asm__("int $3"); うまくいくはずです:

int main(int argc, char** argv)
{
    /* set breakpoint here! */
    int a = 3;
    __asm__("int $3");
    a++;  /*  In gdb> print a;  expect result to be 3 */
    return 0;
}

1
これが好きな#defineので、構文を覚える必要はありません。私はそれを私のコード全体に、時にはの代わりにassert()散りばめています。デバッガを停止してすべての変数とスタックを調べてみましょう。そしてもちろん、断言のように、量産コードのためにそれを削除する必要はありません
Mawgはモニカを2016

興味深いことに、 "Linux"と "GDB"の質問制約がアセンブリ以外の多くのオプションを提供する場合、これは10の賛成票を持ちます。他の答えをいくつか見てください。
ベンジャミンクロフォードCtrl-Alt-Tut


1

OS Xでは呼び出すだけですstd::abort()(Linuxでも同じかもしれません)


どのライブラリですか?
Alex

これは標準C ++ライブラリの一部であり、C ++ 11準拠のコンパイラが存在するクロスプラットフォームです。ただし、これによりSIGABRTが発生します。これは、このインスタンスで発生する適切なシグナルではありません。
Benjamin Crawford Ctrl-Alt-Tut
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.