3

デバッガーでプログラムを実行している場合にのみ停止するassertスタイルのマクロを作成したいと思います。AFAIK、私のボックスで利用できる唯一のデバッガーはgdbなので、それについて説明します。

SIGTRAPシグナルのドキュメントには、デバッガーを一時停止することを目的としていることが示されているので、

if (!assertion) raise(SIGTRAP);

私のコードで。これは適切なポイントでGDBを中断するように機能しますが、コマンドラインからこれを実行するだけでもプログラムが停止します。bashとzshの両方が「トレース/ブレークポイントトラップ」信号を解釈して、プログラムが完全に停止する必要があるためです。

GDBが使用しているが、他のすべてが無視すると予想できるシグナルはありますか?または、デバッガー以外の操作を中断せずにGDBでの実行を一時停止するシグナル以外の方法はありますか?

4

3 に答える 3

4

子をフォークしてptrace親にしようとすることは、あなたがptracedであるかどうかを判断するための、移植可能なUNIXの方法であり、トレースされている場合にraise(signo) のみ実行できます。

ただし、このメカニズムは、またはの下で実行している場合にトリガーされ、プログラムがそれらの下で効果的にクラッシュすることに注意してください。これはおそらく望ましくありません。stracetruss

実装が簡単なLinux固有の方法は/proc/self/status、非を探すこと0 TracerPidです。これには、上記と同じ欠点があります。

Linux固有のもう1つの方法は、、、を呼び出してgetppid、それreadlink("/proc/$PARENT_PID/exe", ...)がGDBを指しているかどうかを確認することです。

Linux固有の例はどちらも、がマウントされていることを前提として/procいます。これは通常は正しいですが、そうである必要はありません。

GDBが使用しているが、他のすべてが無視すると予想できるシグナルはありますか?

これSIGWINCHは通常、非終端記号プログラムでは無視されます。SIGWINCHGDBもそれを無視しますが、次のコマンドを発行することでGDBを停止させることができます。

(gdb) handle SIGWINCH stop print nopass
Signal        Stop  Print   Pass to program   Description
SIGWINCH      Yes   Yes     No                Window size changed
于 2012-12-02T18:47:53.083 に答える
1

GDBのドキュメントには次のように書かれています。

GDBが「Posixシステム」(GNUまたはUnixマシンなど)で実行される場合、GDBは「ptrace」システムコールを介して下位システムとインターフェイスします。

Linuxシステムでは、プロセスを複数の他のプロセスで追跡することはできません。プログラムが親にアタッチしようとする子をフォークする場合、すでにgdbがアタッチされていると、プログラムは失敗します。この失敗を親に通知することは、終了値を使用して行うことができます。

于 2012-12-02T18:30:36.270 に答える
0

デフォルトで無視されるSIGCHLDがあります。gdbは任意のシグナルによってトリガーされると思いますが、無視されたシグナルによってトリガーされる可能性はありません。SIGUSR1のシグナルハンドラーはいつでも作成できますが、これは何もしません(これは、シグナルを無視することと同じではありません。プログラムは中断され、すぐに戻ります)。次に、SIGUSR1を送信できます。通常はプログラムを中止しますが、(指示したため)何も実行されません。シグナルハンドラの設定の詳細については、のドキュメントを参照してくださいsigaction

于 2012-12-02T18:14:50.787 に答える