17

顧客のサイトに展開したCアプリケーションがあります。コンパイルされ、HP-UXで実行されます。ユーザーからクラッシュが報告され、コアダンプを取得しました。これまでのところ、私は家の中でクラッシュを再現することができませんでした。

ご想像のとおり、コアファイル/デプロイされた実行可能ファイルには、いかなる種類のシンボルも完全に含まれていません。gdbにロードしてbtを実行すると、次のようになります。

(gdb) bt
#0  0xc0199470 in ?? ()

ファイルに対して「文字列コア」を実行できますが、実行可能ファイル内のすべての文字列を取得するだけなので、そこにあるものを追跡することは半不可能のようです。

私は実行可能ファイルのデバッグバージョン(-gでコンパイルされた)を持っていますが、残念ながらリリースされたバージョンよりも数ヶ月新しいです。そのハブでgdbを起動しようとすると、次のように表示されます。

warning: exec file is newer than core file.
Core was generated by `program_name'.
Program terminated with signal 11, Segmentation fault.
__dld_list is not valid according to __dld_flags.

#0  0xc0199470 in ?? ()
(gdb) bt
#0  0xc0199470 in ?? ()

デバッグバージョンをコンパイルして顧客のサイトに展開し、次のクラッシュを待つことは可能ですが、いくつかの理由から、比較的困難で望ましくありません。

私はコードに精通しており、顧客のバグレポートに基づいて、コードのどこでクラッシュしているのかを比較的よく理解しています。

このコアダンプからさらに情報を収集する方法はありますか?文字列または別のデバッガーまたは何かを介して?ありがとう。

4

8 に答える 8

9

gdb からのこのタイプの応答:

(gdb) bt
#0  0xc0199470 in ?? ()

スタックがバッファオーバーランによって破壊された場合にも発生する可能性があり、リターンアドレスがメモリに上書きされたため、プログラムカウンタが一見ランダムな領域に設定されます。

これは、対応するシンボル データベースを使用したビルドでも、シンボル ルックアップ エラー (または奇妙に見えるバックトレース) が発生する原因の 1 つです。シンボル テーブルを取得した後もこの問題が発生する場合は、顧客のデータがコードに何らかの問題を引き起こしている可能性があります。

于 2009-06-26T18:50:14.460 に答える
4

gdb の下では、「情報レジスター」は、実行可能ファイルおよび関連する共有ライブラリーの逆アセンブルで使用するために、クラッシュ時の十分な実行状態を提供するはずです。私は通常、objdump を使用して逆アセンブルし、出力をファイルにリダイレクトしてから、お気に入りのエディターでファイルを表示します。また、gdb の「info target」と「info sharedlib」は、共有ライブラリがロードされている場所を把握するのに役立ちます。

レジスタの状態、スタックの内容、および逆アセンブルが手元にあり、少しの運があれば、コールスタックを再構築するのは (面倒だとしても) 簡単なはずです (もちろん、スタックがバッファ オーバーランまたは同様の大惨事によって破壊されていない限り...その場合、ウィジャボードまたは水晶玉が必要になる場合があります。)

-g でビルドされた新しいバージョンの逆アセンブリと、削除されたバージョンの逆アセンブリを関連付けることもできます。

于 2009-06-26T20:08:59.667 に答える
3
  1. テスト リリースであっても、常にソース管理 (CVS/GIT/Subversion/etc) を使用します。
  2. すべてのリリースにタグを付ける
  3. (将来) デバッグ (-g) を使用してビルドを作成し、出荷前に実行可能ファイルを削除することを検討してください。注: -g の有無にかかわらず 2 つのビルドを作成しないでください。-g は、同じ最適化レベルであっても異なるコードを生成する場合があるため、一致しない可能性があります。非常にパフォーマンスが重要なコードでは、重要なファイルの -g を省略できます-ほとんどの場合、違いはありません。
  4. 本当に立ち往生している場合は、スタックをダンプし、ヒープの関連部分を 16 進数にダンプして、手動で確認してください。おそらく、インストルメント化されたコピーを取得し、生成されたコードとスタックで同様の「署名」を探します。これは本当の「昔ながらの」デバッグです... :-)
于 2009-06-26T19:46:16.280 に答える
1

古いバージョンをコンパイルするために使用した正確なソースがありますか (たとえば、ソース ツリーのタグなどを介して)? おそらく、それを使用して再構築し、クラッシュが発生した場所についての洞察を得ることができますか?

于 2009-06-26T18:21:00.390 に答える
0

コアファイルにシンボルが含まれているとは思わない。顧客に出荷したものとまったく同じバージョンのプログラムをビルドできる必要がありますが、-gを使用します。デバッグ実行可能ファイルを削除する場合は、出荷されたバージョンと同じである必要があります。そうして初めて、gdbはあなたに何か有用なものを与えることができます。

于 2009-06-27T14:11:45.557 に答える
0

ここにはあまり情報がありません。バイナリは削除されています。しかし、セグメンテーション違反を見て...メモリの一部を上書きしている可能性がある場所を探す必要があります。

これは単なる提案です。多くの問題が発生する可能性があります。

ところで、ローカル マシンで再現できない場合は、顧客のデータ量が問題になる可能性があります。

于 2009-06-26T18:22:08.250 に答える