Deleaker でメモリ リークを見つける

1 月の初めから、Deleaker というナイスツールで遊ぶ機会がありました。簡単に解読できるように、その主な役割は、ネイティブ アプリケーションのリークを見つけることです。リークを追跡するカスタム コードの作成と維持に問題が発生することがよくありました。そのため、Deleaker はそのような状況で大きな安心感を与えているようです。

それがどのように機能し、ネイティブ アプリの開発にどのように役立つかを見てみましょう。

イントロ

基本的な製品情報:

以下は公式サイトのスクリーンショットです。

ソースファイル、モジュール、リークタイプなどを含むリソース割り当てのリストがあります。選択した割り当てをクリックすると、その呼び出しスタックが表示されます。コール スタック エントリをダブルクリックして、割り当てを担当する特定のコード行に移動することもできます。

仕組み

基本的に、Deleaker は HeapAlloc のように、考えられるすべてのリソース割り当て関数にフックします。 、 CreateFileCreatePen などと HeapFree のような対応するものに 、 CloseHandleDeleteObject など

アプリが割り当てを実行するたびに、スタック トレースが保存されます。アプリケーションの実行中に、すべての割り当てのリストを取得できます。アプリが閉じられると、Deleaker はシステムにリリースされなかったリークを報告します。

簡単な例:書くとき

int *tab = new int[10];

Deleaker は、この特定のメモリ割り当てに関する情報を保存します。コードのある時点で delete [] tab; を使用すると、 その後、Deleaker はこれを適切なメモリ解放として記録します - リークは報告されません。

Deleaker でいくつかのコードをテストしてみましょう。ツールの動作を確認できます。

基本テスト

以前の OpenGLsample から solutiongithub/fenbf/GLSamples を開きました。次に、Deleaker を有効にして、デバッグ モードで実行しました。

アプリの実行中に「スナップショットを撮る」を押しました 」 (Deleaker ツールバー上) で、次の割り当てリストを取得しました:

ご覧のとおり、小さな割り当て (stdand crt ライブラリによって行われる) の全範囲と、アプリによって明示的に行われる 2 つの大きな割り当てがあります。

最初のバッファ (std::unique_ptr に格納) ) は、三角形の元の位置を保持するために使用されます。

2 番目のバッファー (new [] を使用して割り当てられます) ) は、フレームごとに計算されてから GPU に送信される一時データを格納します。

特定の割り当てをクリックして、そのスタック トレースを表示できます。

次に、「X」ボタンを使用してアプリケーションを閉じました。最後に、リークを示す別の「スナップショット」が自動的に保存されます。

上記のリストには、リリースされていない興味深い割り当てが 1 つあります。 delete [] gVertexBufferData を使うのを忘れただけです !!最初のバッファー (三角形用) は適切に削除されました。これは、そこでスマート ポインターを使用したためです。ただし、2 番目のバッファーは明示的に削除する必要があります。

この問題を詳しく調べた後、(Quit 関数で) ESC キーを押すとバッファが破棄されるが、「X」ウィンドウ ボタンを使用するとバッファが破棄されないことがわかりました (その場合、Quit 関数は呼び出されません)。

したがって、次を追加して修正できます。

glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, 
              GLUT_ACTION_GLUTMAINLOOP_RETURNS);

その後、どのような状況でもクリーンアップ関数が呼び出されるようにする必要があります。

その他のリーク タイプ

もちろん、メモリ割り当てはリークの主な原因ではありません。Deleaker はさまざまなシステム ハンドルも追跡できます。これは、codeproject で見つかった人気のあるアプリからのダンプです:

アプリ実行中のスナップショット:

ここで HPEN を見ることができます と HBRUSH アプリケーションによって使用されたオブジェクト。

Deleaker は CreatePen のような関数を探します または CreateSolidBrush .

まとめ

Deleaker を使用した後、このツールを強くお勧めできると思います。数秒で、あらゆる種類のネイティブ アプリから詳細なレポートを取得できます。あなたがしなければならないことは、それを分析して問題を修正することだけです.

機能する、または機能しない可能性があるカスタム コードではなく、個別のツールを使用できることは素晴らしいことです。もちろん、そのようなソリューションを自分で作成することは可能です。それでも、このような追跡をうまく行っているプロジェクトはあまり見たことがありません。さらに、プロジェクトを変更すると、「コピー」にさらに時間を費やさなければなりません。 他のプロジェクトのコードをリークテストします。

VLD のような他の優れたソリューションは非常に役立ちます (しかも無料です) が、メモリー割り当ての追跡しかできません。
Deleaker は、考えられるほぼすべてのリソース割り当て関数にフックするため、より多くの問題を追跡できます。

長所:

  • 非常に習得しやすいユーザー インターフェース。
    • Visual Studio 拡張ウィンドウおよびスタンドアロン アプリとして機能する
  • 多くのリーク タイプを検出します (新規/削除だけでなく…)
    • レガシー アプリケーション、MFC、win32 などに役立ちます…
  • スナップショットを取り、割り当てを比較する能力
  • 完全または圧縮されたスタック ビュー
  • 問題のあるコード行に移動しやすい
  • サポートからの迅速な対応

短所:

  • 場合によっては、CRT、std、さらには MFC など、アプリから直接発生しないリークを除外する必要があります。
    • 報告された、奇妙に見えるリークの公開リストがあるとよいでしょう。そうすれば、リークについて確信が持てない場合でも、それがすでに報告されているかどうかを確認できます。
  • Deleaker を購入 - 30 日間の返金保証付き
  • Deleaker 公式チュートリアル