1. ホーム
  2. c++

[解決済み] デバッグセッションでSigtrapが発生する原因

2022-01-30 08:38:17

質問事項

c++のプログラムで、あるライブラリを使用しているのですが、そのライブラリは、ある操作を行うと、Sigtrapを送信します。 デバッグ中(デバッガとしてgdbを使用)です。その後、プログラムを続行するか停止するかを選択することができます。続行を選択した場合、プログラムは期待通りに動作しますが、Sigtrapを捕捉した後にカスタムブレークポイントを設定すると、デバッガとプログラムがクラッシュしてしまいます。

そこで質問です。

  1. このようなSigtrapが発生する原因は何でしょうか?それとも、デバッガが気に入らないものを見つけたときに発生するのでしょうか?
  2. もしそうなら、なぜデバッグ版ではなくリリース版をコンパイルすると、プログラムが完璧に実行されるのですか?
  3. Sigtrapは何を示しているのですか?

これは、昨日投稿した質問に対するより一般的なアプローチです。 Boost Filesystem: recursive_directory_iterator コンストラクタが SIGTRAPS とデバッグ問題を引き起こす .
私の質問はあまりに具体的で、私の問題を解決してほしいのではなく、私(そしてできれば他の人)が背景を理解するのを助けてほしいのです。

ありがとうございました。

どのように解決するのですか?

命令ブレークポイントやデータウォッチポイントをサポートするプロセッサでは、デバッガはCPUに特定のアドレスへの命令アクセス、または特定のアドレスへのデータリード/ライトを監視するよう依頼し、全速力で実行します。

プロセッサがイベントを検出すると、カーネルにトラップし、カーネルはデバッグされているプロセスにSIGTRAPを送信します。通常、SIGTRAP はプロセスを強制終了しますが、デバッグ中であるため、デバッガはシグナルを通知され、主に実行を継続する前にプロセスの状態を検査させることで処理します。

ブレークポイントやウォッチポイントをサポートしないプロセッサでは、デバッグ環境全体がコード解釈とメモリエミュレーションによって行われるため、非常に遅くなると思われます。(私は、ページテーブルのフラグを設定して、読み取りまたは書き込みを禁止し、トラップする必要がある方を、カーネルにページテーブルを修正させ、デバッガに通知し、その後ページフラグを再び制限することによって、巧妙なトリックを行うことができると想像しています。これはおそらく、ほぼ任意の数のウォッチポイントとブレークポイントをサポートし、ウォッチポイントやブレークポイントが頻繁にアクセスされない場合にのみ、わずかに遅く実行することができます)。

コメント欄に記入した質問は、Windows が実際に SIGTRAP を送信しているのではなく、独自の方法でブレークポイントを通知しているため、ここでも適切な質問と思われます。プログラムをデバッグしているとき、システムライブラリのデバッグバージョンが使用され、メモリアクセスが意味をなしているように見えることを確認すると思います。実行時には隠蔽されているプログラムのバグが、実は別のところでさらなる問題を引き起こしているかもしれないのです。

Windowsで開発したことはないのですが、Windowsのイベントログを見ればもっと詳細がわかるかもしれませんね?