blogプログラムやゲーム、旅、愛する家族について綴っていきます。プログラミングはじめに過去のプロジェクトでマスター直前に出たメモリ破壊のバグを調査した時の方法を公開します。報告内容プラットフォーム:コンシューマ言語:C++症状:メモリアロケート時に門番の情報が破壊されているらしく、不正チェックに引っかかり、ASSERTで停止。タイミングは不定、アドレスも不定な為ハードウェアブレイクでも追うのが困難な状況。再現頻度はかなり低い。今ところはデバッグ版のみで発生。リリース版はエラーチェックに引っかからないので発覚していないだけで、メモリは破壊されている可能性はある。調査開始かなりやっかいなメモリ破壊系の不具合報告が来ました。破壊している箇所がたまたま門番の場所だったのでその領域を解放した時のチェックで発覚しました。メモリアロケート時に不正チェックに引っかかっているということは、それ以前のどこかのタイミングで破壊されていると思われます。したら他のデータ領域を壊している可能性もありますし、その場合壊されたことに気が付かず動作し続けている可能性もあります。追っているがとっかかりがない状況です。他のメンバーはマスター直前で他のチケットにかかりきりで誰も調べられていません。可能性を考えてみます。頻度は高くないが壊されたメモリを確認してみると、必ず1バイトが書き換わっている様で前後の門番のフィルの状態は壊されていませんでした。バッファオーバーランの可能性もありますが、仮にそのオブジェクトのインスタンスでメモリを破壊してそのタイミングで門番を破壊しているようであればそのインスタンスが破棄されたタイミングなどでもエラーが出てもよさそうなものです。変数の書き込みを疑ってみることにします。いうことで以下の様なことをやって書き込みのタイミングで拾うようにしてみました。調査方法プロジェクトでは固有の型が定義されています。簡潔に書くために便宜上以下の様にしています。:変数の書き込みのタイミングでチェックを行うために以下の様なclassを定義します。力技ですがboolやs8,u8という型をGrepでBool,S8,U8に置換します。これで今までと同じ挙動で変数の型を置き換えることができました。ヒープのフリー領域や門番等のアドレスかどうかをチェックします}この仕組みを施してテストに回したところ、テストプレイで見事にチェックに引っかかりました。担当者に報告してデバッガ上で再現してもらい確認してもらったところ、デバッグ機能側で解放されたオブジェクトに対して操作を行っていたらしいです。デバッグ機能というところまで絞り込めたので、そこまで分かれば再現手順も絞り込めます。担当者に修正してもらい、テストプレイでも再現しないことが確認できました。最後に今回は本当に1バイトの変数の書き込みのタイミングだったのでバグが特定できましが、違う不具合だったらどう対処してたんでしょうか...他にももっとスマートな解決方法があったもしれません。そもそも論で言えばスマートポインタのような仕組みで設計、実装されていればというのもありますが、起きてしまったバグはなんとか潰さなければなりません。手法はどうあれ問題を解決することが重要です。同じやり方でというケースはないかもしれませんが何かの参考にでもなればと思います。みなさんもやっかい系のバグに出くわして、こういう風に解決しましたという事例があったら教えてください。そもそもバグに悩まされるのがいやなので、こちらの関連記事も読んでみてください。はてなブログProプログラムやゲーム、旅、愛する家族について綴っていきます。C++はてなブログをはじめよう!takezoh_1127さんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。