4

一連の単体テストを備えたWin32C++アプリがあります。単体テストの実行が終了したら、解放されていないメモリに関する人間が読める形式のレポートを自動的に生成したいと思います。理想的には、レポートには、解放されていない各割り当てのファイルと行番号情報を含むスタックが含まれます。ある実行から次の実行への差分を容易にするために、それらを一貫した順序で生成しておくと便利です。(基本的に、valgrind --leak-check = fullの結果が必要ですが、Windowsでの結果が必要です)。

私はUMDHが実行中のプロセスからこの種の情報を取得することに成功しましたが、そのツールは既存のプロセスに接続した場合にのみ機能するようです。単体テストを実行するたびに、これが自動的に行われるようにしたいと思います。

これを行うことができるツールはありますか?もしそうなら、私はそれをどのように使用しますか?

ありがとう!

4

5 に答える 5

4

この種の情報を取得するために、new/delete と malloc/free をオーバーライドし、割り当て時にスタック トレースを格納し、ヒープが破棄されたときにレポートを生成する独自のヒープ実装を提供します (また、バッファ オーバーランを検出するためにセンチネルを追加します)。

これは、初めて行う場合はかなりの作業です。この男は、すべてのハードビットを処理するフリーウェア ツールを作成しました。私自身は試していませんが、作成方法についての彼の説明は、自分で作成するときに役立ちます。

于 2008-10-03T22:19:49.870 に答える
1

MSVC を使用している場合、Microsoft のデバッグ ヒープ関数を使用して必要なレポートを生成できますが、必要なほど自動化されない場合があります (カスタム コードを記述する必要がある場合があります)。

_CrtSetReportMode
_CrtSetReportFile
_CrtMemState    
_CrtMemCheckpoint
_CrtMemDumpStatistics
_CrtSetReportFile
_CrtSetDbgFlag
于 2008-10-03T22:12:03.427 に答える
0

私は一度これを行いましたが、それほど自動ではありませんでした。私は今そのコードにアクセスできませんが、アイデアは次のとおりです。

Mike B が言及したデバッグ機能を使用しました(ところで、これらはデバッグでのみ機能します)。

最初の実行時にグローバルにメモリが割り当てられるため、テスト ランナーはすべてのテストを 2 回実行しました。2 回目は、割り当てられたブロックの合計数が各テストの前後にチェックされました (setUp() と TeaDown() で実行できると思います)。数値が異なる場合は、メモリ リークを意味し、適切なメッセージが表示されてテストが失敗しました。もちろん、テスト自体が失敗した場合は、そのエラー メッセージを保持する必要があります。リークを見つけるには、pBlockHeader を使用して最後の割り当てのブロック割り当て番号を読み取り、_CrtSetBreakAlloc を使用してブレークポイントを設定し、再度実行する必要がありました。

詳細はこちら: http://levsblog.wordpress.com/2008/10/31/unit-testing-memory-leaks/

于 2008-10-04T19:25:36.120 に答える
0

Mike B さんが指摘してくれた CRT デバッグ ヒープ関数をいじってみましたが、結局、リークしたメモリのアドレスを取得するだけでは満足できませんでした。UMDH が提供するようなスタックを取得すると、デバッグが非常に高速になります。そのため、main() 関数では、テストを実行してヒープ スナップショットを取得する前後に、CreateProcess を使用して UMDH を起動します。また、テスト ハーネスを実行してからヒープ スナップショットを比較する簡単なバッチ ファイルも作成しました。そこで、バッチ ファイルを起動して、テスト結果と、解放されていない割り当ての完全なスタックを含むテキスト ファイルを一度に取得します。

UMDH は多くの誤検知を検出するため、おそらく CrtDebug と私が現在行っていることのハイブリッドがより良い解決策になるでしょう。しかし、今のところ、私は自分が持っているものに満足しています。

ハンドルを閉じていないかどうかを検出する方法があれば...

于 2008-10-04T22:45:32.797 に答える
0

DEBUG_NEW を定義すると、リーク検出がオンになります。システム インクルード ファイルを含める前に定義する必要があります。new 演算子を使用してリークをチェックするだけであり、もちろんコードを再コンパイルする必要があるため、valgrind のようにアタッチすることはできません。

ここで詳細情報を参照してください:

http://msdn.microsoft.com/en-us/library/tz7sxz99(VS.80).aspx

于 2008-10-03T22:45:05.967 に答える