メモリリークの調査

service.exeがメモリリークする - MSDN フォーラム


Windows CEメモリリークの原因を特定するには大雑把に言って3種類ある。(標準環境だけを使う場合。サードパーティソリューションもあったと思うが使ったこと無いのでここでは扱わない)


実行形態 アプリ ドライバ 難易度
AppVerifier リモート接続 ×
リモートカーネルトラッカ+Memalyzer リモート接続 普通
celog+Memalzer スタンドアローン

(1)AppVerifier

プラットフォームマネージャ(KITL、ActiveSync、TCP/IPなど)でリモート接続した環境で、ターゲットアプリをリモートで起動して、メモリリークを検出することが可能。
操作は簡単、AppVerifier起動、デバイスにリモート接続、リモートでアプリ起動、操作、終了するだけ。あとはAppVerifierが未解放のメモリアロケーションを一覧表示してくれる。
参考:ソフトウェア開発ライフサイクル内で Application Verifier を使用する

(2)リモートカーネルトラッカ + Memalyzer

リモートカーネルトラッカを使って、OSのトレースデータを収集する。収集したデータを*.clgファイルとして保存し、Memalyzerで解析を行う。
リモートカーネルトラッカは、リモート接続(プラットフォームマネージャ)できる環境であれば使えるので難易度は(3)に比べ低い。ただしリモートなのでちょっと重いし、PCとオンラインでなければならないのでサスペンド/レジュームに絡んだメモリリークの調査には使えない。
※リモートカーネルトラッカは、リモートでcelogを動かすので本質的には(3)と変わらない。(3)をリモートコントロールできるようにしただけと考えればよい
参考:リモート カーネル トラッカ

(3)celog + Memalyzer

唯一この方法のみ、デバイススタンドアローンで調査を完結できる。PCと接続する手段が無いデバイスや、サスペンド/レジューム時のメモリリーク調査に超有効。
ただし、celog関連のモジュールを自分でビルドして、celogトレースデータをデバイス上の手操作で収集しなければならないので難易度は高め。
celog関連のモジュールは以下にあるので自力でビルドして(必要に応じてカスタマイズして)使う。
%_WINCEROOT%\PUBLIC\COMMON\SDK\SAMPLES\CELOG\FLUSH\CELOGFLUSH
%_WINCEROOT%\PUBLIC\COMMON\SDK\SAMPLES\CELOG\FLUSH\STOPFLUSH
Platform Builderのコマンドライン

sysgen -p common celogflush

を実行すればcelogflush.exeが出来上がる。celogstopflush.exeは、SYSGEN定義に含まれていないので自分でビルドしなければならない。
celogflush.exeは、celogでのトレースを開始する。
celogstopflush.exeは、トレースを終了する。
出力されたトレースデータ(*.clg)を開発PCに持っていって、Memalyzerにかけるだけ。あとは(2)と同じ



上記の3種類のいずれも、Alloc時のスタックトレースデータと確保したメモリサイズを確認できるので、具体的にどのプロセスの、どのモジュールのどの関数でメモリリークしているかまで特定できる。(ただし_FLATRELEASEDIRに存在する*.mapなどのデバッグ情報が必要)
事前にアセンブリ出力ファイル(*.cod)を用意しておけば、関数内のアドレス単位(≒ソース行単位)でメモリリーク箇所をピンポイントで特定することも可能。まあ、そこまでしなくても関数さえわかれば普通はHeapAllocとかVirtualAllocとかの呼び出し箇所は十分特定可能だが。関数内でたくさんAllocしている場合はこの方法が有効になる。


Memalyzer(メマライザー?メムアライザー?)はundocumentedなツールだから、知名度が全く無い。ググっても13件しか出てこないという有様…。でも超強力なツール。使い方を覚えて損はなし。使い方、といっても、*.clgを入力してHTMLで解析結果を出力してくれるだけのツールなので使い方もへったくれもないのだが。
公式ツールになる日は来るのか…?


なお、memalyzerは %_WINCEROOT%\PUBLIC\COMMON\OAK\BIN\I386 に入っているが、Platform Builderのコマンドラインを起動すればパスが通っているのでそのまま memalyzer で実行できる。

memalyzer -out:html XXXXX.clg

とすればdefault.htmを出力してくれる。memalyzer -h でヘルプ。