2016-06-16 9 views
2

私はヒープ上に配置されたオブジェクトがたくさんある非自明のソフトウェアプロジェクトをデバッグしています。ある時点で(少なくとも)これらのオブジェクトの1つが壊れてしまいます。ヒープ上の破損したオブジェクトのデバッグ

私はカナリアンとして機能するためにクラスにconstメンバーを追加しましたが、実際には実行中に破損します。通常、私はこの変数にウォッチポイントを追加して、いつメモリが書き込まれるか把握します。しかし、クラスに格納されている情報も破損するため、どのインスタンスが上書きされるのか分かりません。

各オブジェクトにウォッチポイントを設定するにはオブジェクトが多すぎますが、小さな入力セットでは再現できませんでした。 valgrindを実行しています私は "無効なサイズ4の読み取り"を参照してください、これは4バイトの私のカナリアンのintを読み取っているが、この時点ではすでに遅すぎます。

ここから進める方法についてのご意見はありますか?

+0

タイトル:「ヒープ上」。質問: "スタック上に"。あなたの心を補ってください。 – molbdnilo

+0

破損が発生する前にオブジェクトの一部が削除されていますか? '無効なサイズ4の読み込み'は、解放したメモリのように、または割り当てられたメモリブロックの外にはならないデータを読み込んでいることを意味します。 valgrindより詳しい情報を提供していませんか? 完全なvalgrindトレースを投稿できますか? – Tryum

+0

ソースコードを確認してください。そのような腐敗が起きる可能性があるあなたは何をしていますか?プログラムはマルチスレッドであり、適切な同期が使用されていませんか?これらのオブジェクトへのポインタは共有されていますが、所有者の1人が他の所有者に通知せずにメモリを解放している可能性があります。その他 – PaulMcKenzie

答えて

1

私は自分の問題の原因を突き止めることができました。私が最初に見つけたことのないオブジェクトを作り出します。 @ employ-russianのように、自分のオブジェクトが私が気づいていなかったどこかで削除されているかもしれないかどうか疑問に思いました。デストラクタにブレークポイントを設定すると何も得られませんでした。唯一の合理的な説明はポインタ自体が無効で、メモリのクラスが有効ではないことを指しています。

Loです。逆参照されたポインタは別のクラスのコンストラクタによって初期化されずに残っていました。私はNULLを明示的にチェックして、ValgrindのエラーがConditional jump or move depends on uninitialised value(s)になったときにそれを理解しました。 --track-origins=yesを使用すると、初期化されていないデータのソース、つまり初期化リストから欠落しているポインタがすぐにわかりました。

(私は初期化されていない値が-Wuninitializedと、コンパイラによって検出することができます知っているが、明らかに打ち鳴らす(りんご)の私のバージョンが有効になって-Wallとそれを言及するように感じることはありませんでした。)

1

これは具体的なものではありませんが、同様の問題が発生した場合は、ここで私がやったことがあります。私は決定的な方法で問題を再現できると仮定しています。

私の戦略は、問題の原因となったインスタンスを見つけることでした。これは症状を露呈させる特定の行のカウンターで行いました。たとえば、Visual Studioでは、100000番目のヒットでトリガするブレークポイントを設定します。 Visual Studioでは、実行中にブレークポイントが何回検出されたかが表示されます。試行錯誤によって、問題がブレークポイントが発生した20回目に発生することがわかります。そのため、破損が発生する前に適切なインスタンスを識別できるように、ブレークポイントを19回目の繰り返しでトリガーするように設定します。

ここからは、以前に壊れていた変数のアドレスを知り、デバッガで何が起きているのかを調べることができます。障害のあるインスタンスに関する十分な情報を収集します。

次に、条件によってトリガされた戦略的な場所でブレークポイントを設定しました。適切なアドレスを持つインスタンスのみ、またはメンバー内の特定の値を使用してトリガーします。

症状は正確には発生しますが、問題にはならないでしょうが、それでもなお問題はあります。

希望すると便利です。

+0

これは面白いアプローチのように聞こえますが、私は間違いなく将来のデバッグセッションに留意しています! – Jonas

1

実行中valgrind私は4バイトの読み込み中の私のカナリアンのintですが、この時点では既にそれは遅すぎます。

あなたは混乱している:valgrindのは、あなたが、あなたはdanging(すでに解放された)オブジェクトを読んでいる(オブジェクトが解放されていたためと思われる)、無効な読み取りを行っていることを言った場合、それは正確にであるあなた問題。

このようなオブジェクトにアクセスしようとしないでください。オブジェクトを解放/削除した後にカナリーが変更/破損したという事実は無関係です。

関連する問題