web-dev-qa-db-ja.com

デバッガを使用していない場合のみセグメンテーション違反

マルチスレッドのCプログラムがあり、プログラムの特定のポイントで一貫してセグメンテーションフォールトを生成します。 gdbで実行すると、エラーは表示されません。デバッガーを使用していない場合にのみ障害が発生する理由を考えることができますか?問題を見つけるためにそれを使用することができないのはかなり迷惑です!

51
Benubird

クラシック ハイゼンバグ 。ウィキペディアから:

時間もヘイゼンバグの要因になります。デバッガーの制御下でプログラムを実行すると、通常の実行と比較してプログラムの実行タイミングが変わる可能性があります。デバッガーでソース行を1ステップ実行することによりプログラムの速度が低下すると、競合状態などの時間依存のバグが再現しない場合があります。これは、2つのマシン間でネットワークパケット処理をデバッグし、1つだけがデバッガー制御下にある場合など、動作がデバッガーの制御下にないエンティティとの対話を伴う場合に特に当てはまります。

デバッガーがタイミングを変更し、競合状態を隠している可能性があります。

Linuxでは、GDBはアドレス空間のランダム化も無効にし、クラッシュはアドレス空間レイアウトに固有のものである場合があります。 (gdb) set disable-randomization off

最後に、 ulimit -c unlimitedおよび事後デバッグ(Robieが既に提案)が機能する場合があります。

74
Mehrdad

おそらく、gdbを使用する場合、メモリは、オーバーフロー/アンダーフローがクラッシュの原因となるメモリを踏みにじらない場所にマップされます。または、トリップしなくなった競合状態である可能性があります。直感的ではないように聞こえますが、happyである必要があります。

いくつかの提案

  1. Free cppcheck などの静的コードアナライザーを試してください。
  2. libefence のようなmalloc()デバッガを試してください
  3. valgrind で実行してみてください
7
SiegeX

デバッグすることで、実行中の環境を変更します。何らかの競合状態に対処しているように聞こえます。デバッグすることで、問題が発生しないようにスケジュールが少し異なるように見えます。それ、または物事がわずかに異なる方法で保存されているので、それは発生しません。問題を理解するのに役立つデバッグ出力をコードに入れることはできますか?これにより、影響が少なくなり、問題を見つけることができます。

5
Mark Loeser

私は以前にこの問題を完全に経験しました!それは競合状態であり、デバッガーを使用してコードを実行したときにスレッドiが実行されていたので、競合状態をトリガーしないほど十分に低速でした。かなりひどい。

2
rook