2011-03-01 14 views
4

外出先アプリケーションの開発中に、特別なことがありましたが、本当に厄介なバグがありました。この症状は、プロセスが消えるという単純なものです。ログは突然終了するだけで、クラッシュダンプなど何も見つかりません。ゾンビプロセスは存在しません。ワトソン博士は何の痕跡も残さずに私たちを離れることに気づいていません。トレースレスクラッシュをデバッグする方法

エラーは再生するのが簡単ではなく、このエラーを再現するのに平均して3〜4時間かかります。同じ操作を繰り返し実行します。だからどこかには何らかの競合状態があります。 SEHと通常の例外の両方を扱う特別な関数があるので、これらのどれも気付かれないようにしてください。

特殊なハードウェア上で実行されているため、デバッグは特別なコンピュータで行う必要があります。したがって、リモートデバッグだけが利用可能です。また、リモートデバッグが接続されている場合、C++ビルダーは、アプリケーションが存在しないことに気付かず、存在しないプロセスでデバッグしようとするとクラッシュして焼き付きます。

私たちは、このソフトウェアとテクノロジーの多種多様な使用している:

  • OpenGLを
  • のDirectShow +いくつかのCOTSフィルタ
  • COM/DCOM、専用のハードウェアに話し
  • シリアルCOMポート
  • C++ Builder(VC++とは異なるスタックフレームを使用する)

あなたが理解しているように、私はここで多くのことをする必要はありません。私が今やっているのは、エラーが発生したコードに特定の点があるかどうかを見つけるために、コード内の別の場所にログインして絞り込むことです。私は、できるだけ単純なケースを得るために、私が実行しているアクションの多くの側面を削除しようとしています。しかし、これは実際には複雑な操作であり、このプロセスには多くの時間がかかり、時間は(通常通り)希少なリソースになります。

誰かが私のために良いヒントを持っているのだろうか(一般的にはプロセスが何の通知もせずに停止する原因)か、そのような致命的なエラーをデバッグするテクニックには疑問がありますか?

+2

私はこのバグのクラスに「バミューダ・トライアングル・バグ」という名前を付けます。 – caf

+0

これを実行しているWindowsの正確なバージョンは何ですか? – Argote

+0

これはカスタマイズされた組み込みXPで実行されています。 – daramarak

答えて

1

シナリオをより頻繁にデバッグできるようにするには、仮想マシンでこれを実行し、発生する前に「スナップショット」を頻繁に取ってみてください。

ここで問題となっているのは、シリアルポート経由で接続した特殊なハードウェアの状態と矛盾する場合があります。

+0

まず最初に、ハードウェアは環境を仮想化することができません。第二に、ハードウェアの状態がプロセスにどのような影響を与えるかを理解できません。シリアルポート経由でのみアクセスできます。だから、その中のエラーは、ファームウェア、通信の問題がハングアップする可能性がありますが、プロセスの終了??? – daramarak

2

windbgを試してみないと、名前付きパイプまたはシリアルポート経由でリモート接続することもできます。


NO BSOD、ないルートキット、無楽しい~~ Biswanthチョードリー - Win32のカーネル*

+0

私はwindbgが未知のスタックフレームに問題を起こすだろうと思っていますが、それでもまだ私が持っている以上のアドレスを与えるならば。私はそれを見ます。 – daramarak

+2

グーグルの 'windbg Borland'は、関数名は取得できますが、変数名は取得できないことを示しています。 – MSalters

+0

@MSalters、ありがとう、私はそれを知らなかった。私は他のvC++のセントリックツールを先に試しましたが、多くの情報が得られていませんが、これを知っていれば間違いなく試してみます。 – daramarak

7

Windowsでネイティブコードは(一般的に起因する無限再帰に)スタックオーバーフローを経験するとき、プロセスは時々消えますまさにあなたが描いている通りです。標準的なエラーダイアログと例外処理にはいくつかのスタックスペースが必要で、残っていない場所では実行できません。 (Windowsのそれ以降のバージョンではこれがより良く処理され、は常にが例外を発生させるはずです.Windows XPはこの定義では「後で」ありません。)

これをデバッグするもっとも簡単な方法は、ログメッセージを各機能のエントリ(および場合によっては終了)に書き込むことです。これらのメッセージにはが直接ファイルに格納されます。バッファされた出力(たとえば、coutなど)の場合は、その都度直ちにフラッシュしてください。クラッシュを起こすと、少なくともその問題をローカライズできるスタックトレースが近くにあります。


無限再帰は(より一般的ですが)スタックオーバーフローの唯一の原因ではありません。スタック上に非常に大きな変数(通常、数千から数百万の要素を含む配列)が割り当てられている場合、同じ問題が発生する可能性があります。特に、alloca()「機能」は、このタイプのスタックオーバーフローの原因を隠す可能性があります。

ガードページの例外をデバッガとブレーク/ログオンして実行すると、スタックが拡張されているときに通知されます。メモリをより多くコミットするために使用されているため実際には関連しない問題。


消滅プロセスの最終非スタックオーバーフローの原因はexit()またはExitProcess()に浮遊呼び出しです。フルテキスト検索では、これをほとんど排除できるはずです。デバッガのExitProcess関数のブレークポイントは完全にそうするでしょう。

+2

+1は、独自のトレースログを記述するためのものです。不明なものをデバッグしようとすると、ロギング情報のすべてのビットがゴールドに似ています! – Matt

+0

あなたは正しいかもしれませんが、スタックオーバーフローが発生した場合にOSが通知しなければならない構造化例外処理(SEH)を設定しています。以前のケースでは、スタックオーバーフローが発生していましたが、通常はdr.watsonが反応し、プロセスが強制終了されたという通知が表示されます。 coutのデバッグは私が今やっていることです。うまくいけば、それはいくつかの結果をもたらすでしょう。 – daramarak

+2

@daramarakシステムに依存します。私はちょうど短いテストアプリケーション(アセンブリで、 'start:push 0 jmp start')を書いて、Win7 x64では' STATUS_STACK_OVERFLOW'を生成しますが、WinXP x86では消えてしまいます。あなたが試すことができるもう一つのことは、スタック制限を減らすことです(リンカオプションにあるべきです)、エラーが早く発生するかどうかを調べることです。 – Zooba

2

ヒープを小さくして実行してください。メモリ不足が原因で問題が発生した場合は、クラッシュが早期に発生します。

関連する問題