2011-02-12 2 views
0

私はLinuxで動作するこの古いC++プログラムを開発中です。私が今までに読んだことのない最悪のコードで、ValGrindで実行すると、数多くのメモリ問題が発生します。Segフォールトデバッグに関する提案が必要

私は1つでワンセグ障害の1を狙い撃ちにしたいが、時間によってValgrindのは、被害のコードがクラッシュが行われている行を検索します。このコードでは、サードパーティ製のライブラリと家庭用のライブラリを使用しています。サードパーティのライブラリは信頼できるものの、自宅は成長できません。

segフォルトの原因となるメモリ破損の発見方法については、他に提案はありますか?他の人のコード、特にドキュメンテーションなしでリリースされたコードでは、segフォルトを見つける必要はありませんでした。

今日私が知った2つのことは、コンパイラの設定が自動的に初期化されないように変更されたことです。ワードサイズが32ビットから64ビットに変更されました。

私はどんな先走りをしようとしていますが、誰かが深い記憶分析のアイディアを持っていますか?

ありがとう

+0

私はgdbでDDDを使用しています –

答えて

0

GDBは良い提案です。また、プログラムがクラッシュしたときに、ulimit unlimitedman page)を使用して、コアファイルをダンプするシステムを取得することもできます。

つまり、これらのツールが提供する情報は、メモリエラーを処理する際に誤解を招く可能性があります。メモリ破損は、問題の原因とはほとんど関係のないランダムな場所でプログラムをクラッシュさせる可能性があります。コアダンプやGDBの出力を見て、プログラムがどのようにその状態になったのか疑問に思っているなら、これが起こっている可能性が高いです。

このような場合、valgrindはあなたの親友です。メモリエラーのリストの一番上から始めて、一度に一つずつ修正してください(修正することを意味し、再実行してから次の修正を行うなど);これは一つのエラーを修正することで、 )彼らがすべてなくなるまで。その後、あなたのプログラムはより安定しているか、ツールが役に立つ情報を再度提供します。

+0

一度に一つのvalgrindエラーを処理したいのですが、init-errorが発生しているlibsに問題があり、アクセスできません。このプログラムは、私の理解から巨大な二重リンクリストのように動作し、損傷はリンクを削除するように見え、segフォールトは永続的なファイル書き込みで起こります。保存操作が行われるずっと前に、メモリーが破損しているときにvalgrindまたはデバッガーを停止させることはできません。 –

+1

便利なトリックの1つは、すべてのオブジェクトがすべてのポインタをデストラクタでnullに設定することです。そうすれば、コードが解放されたオブジェクトを使用しようとすると、最終的なクラッシュに至る未定義の動作ではなく、即時のセグメンテーションが発生します。また、何もできないエラーを無視するようにvalgrindを設定することもできます。私はちょうど私の頭の上を思い出すことはありませんが、ドキュメントはあなたに伝えるべきです。 –

+0

私はこれを試すことができます、唯一のドローコードはかなり大きいです。 –

0

gdbはおそらくvalgrindよりも優れています。あなたのアプリケーション(gdbで動作している)がSIGSEGVを受け取ると、gdbは実行を中断し、スタックトレースを生成し、その時点までにどの関数が呼び出されたかをリストし、プログラムのメモリの状態を保存します。これを行うには、デバッグ情報(gccの-g)を使用してアプリケーションをビルドする必要があります。ライブラリを再構築できない場合でも、プログラムのメモリの保存は大きな助けになるでしょう。

0

メモリ破壊をデバッグする最も簡単な方法は、それが起こるの後に、好ましくは、正確な時間で、可能な限り早期に破損をキャッチすることです - これはあなたが故障しているどのスレッドおよび方法を参照することができます。

一般に、破損は、破損後にしばらくの間しか発生しないため、分かりにくいです。 Valgrindと他のツールは、バッファオーバーフローや他のオーバーレイが捕捉されているかどうかを確認するために、いくつかのチェックを採用することで、破損の早期発見に役立ちます。

は、ユーザガイドを見てみるか、あなたがクラッシュを強制や破損の近くにブレークポイントを設定できるかどうかを確認するために、代替のツールを試してみてください。自然のクラッシュポイントでデバッガを使用すると、破損したメモリに関する情報を明らかにすることができ、時にはそれが難しい強打することができ、言わ

。 valgrindのようなツールは、問題がなくなるか、容認できないほど低いパフォーマンスを引き起こさない場合、非常に重要です。

0

メモリアロケータでデバッグ機能を有効にできるかどうかを確認してください。 glibcのmalloc実装には何とかして有効にできるいくつかの健全性チェックがあります。

私はかつてアプリケーションが使用されていたメモリアロケータの内部データ構造を上書きしてしまった(単純なチェーンベースのmallocを持つ組み込みシステムで) - メモリ割り当てに散発的なsegfaultを生じました。

0

ありがとうございました。誰にも分かりませんが、valGrindが私の問題を発見しました。コードは、必要な保存操作の前にオブジェクトを削除していたようです。それは私には少ししかかかりませんでしたが、valgrindのための出力を得るためには何が間違っていたのか死んでいました。