2012年3月11日日曜日

ヒープ破壊のチェック方法@Windows

大方のAndroidプログラマの方には無縁だと思いますが、私が作るアプリの場合、コードの9割強がC/C++で作られているので、ヒープ破壊のバグが発生すると、必然的にデバッグが極めて困難になります。
勿論、ダンプが取れれば、壊れた形跡から概ね何処で壊したか特定できますが。
ヒープ破壊の厄介なところは、壊れ方によっては、何の問題も無く動いてしまうところ。
(スタック破壊なら、/RTCsオプションとかでチェックできますが)

Linuxであればvalgrindを使えば、ヒープ破壊のチェックができますが。
しかし、WindowsのC(VisualC)でAndroid用のソフトを開発している私の場合、それは無理。

RationalのPurifyを使えば、チェックできますが、色々と設定が面倒くさい。
インストゥルメントしてしまうと、動きも重くなってしまうし、モノによっては正常に動かなくなります。
ついでに、結構値段が高いPurifyを個人で買うのはちょっと・・・

Windowsで、お金を掛けずにヒープ破壊のチェックをしたければ、Debugging Tools for Windowsの付属ツール(gflags)を使い、未確保の領域を触った時点でクラッシュさせてあげれば良いです。

gflags -p /full /enable 実行ファイル名

という感じでやってから実行ファイルを実行すれば、未確保の領域を触ったときに落ちてくれます。
あと、実行ファイルをコンパイルする際に/Ziオプションを付与してデバッグ情報をオブジェクトモジュールに設定し、リンク時に/DEBUGオプション+/PDBオプションでPDBを作ってあげれば、コールスタックから落ちた位置を簡単に特定できます。

Debugging Tools for Windowsは、Microsoftからタダで落とせます。
かなり便利なツールの宝庫なので、色々と使ってみると楽しいですよ。
ドキュメントは全部英語なので、読むのが面倒くさいですが。


追記: ちなみにゲームの場合、ヒープは起動時に全部確保して、停止時に全部開放します。
動作中は動的メモリを一切確保せず、リングバッファのみで情報を管理するのが普通。
実は、ヒープの確保は結構重いので、仮に大した量でなくてもそうすることが、ゲーム作りでは常識。
ちなみに、私にはもう関係無いことですが、Javaの場合、アプリはJヒープ(JavaHeap)という領域を使いますが、これはもっと重い。
多分、Javaを開発した当初は、エクスプリシット(参照カウンタが全部外れれば解放する)で作っていたと思うのですが、Jヒープの余りの重さに悩んだSunの技術者が、「ヒマな時に解放すればよいんでない?」程度の浅はかな考えで、GCなる処理を作ったんだろうと思います。(私はSunの人間ではないので単なる勘ですが)
Javaでゲームを作っている人は大変だろうなぁ・・・と、思います。

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。

合理的ではないものを作りたい

ここ最近、実機版の東方VGSの開発が忙しくて、東方VGSの曲追加が滞っています。 東方VGS(実機版)のデザインを作りながら検討中。基本レトロUIベースですがシークバーはモダンに倣おうかな…とか pic.twitter.com/YOYprlDsYD — SUZUKI PLAN (...