Memory leak detection while running unit tests

2019-03-31 02:19发布

I've got a Win32 C++ app with a suite of unit tests. After the unit tests have finished running, I'd like a human-readable report on any unfreed memory to be automatically generated. Ideally, the report will have a stack with files & line number info for each unfreed allocation. It would be nice to have them generated in a consistent order to make it easy to diff it from one run to the next. (Basically, I would like the results of valgrind --leak-check=full, but on windows).

I've had success with UMDH getting this kind of info from running processes, but that tool only seems to work if you attach to an existing process. I want this to happen automatically every time I run my unit tests.

Is there a tool that can do this? If so, how do I use it?

Thanks!

5条回答
Rolldiameter
2楼-- · 2019-03-31 02:57

If you're using MSVC, Microsoft's Debug heap functions can be used to generate the report you want, but it may not be as automatic as you'd like (you may need to write some custom code):

_CrtSetReportMode
_CrtSetReportFile
_CrtMemState    
_CrtMemCheckpoint
_CrtMemDumpStatistics
_CrtSetReportFile
_CrtSetDbgFlag
查看更多
放我归山
3楼-- · 2019-03-31 02:59

I did this once, but it wasn't quite as automatic. I don't have access to that code now, but here's the idea:

I used the debug functions that Mike B has mentioned (btw, they only work in Debug).

The tests runner ran all tests twice, because during the first run memory is allocated for globals. The second time, the total number of allocated blocks was checked before and after each test (I think you can do it in setUp() and tearDown()). If the number was different, it meant a memory leak, and the test failed with an appropriate message. Of course, if the test itself fails, you should preserve its error message. Now to find the leak, I had to read the block allocation number of the last allocation using pBlockHeader, then set a breakpoint on it using _CrtSetBreakAlloc and run again.

More on this here: http://levsblog.wordpress.com/2008/10/31/unit-testing-memory-leaks/

查看更多
不美不萌又怎样
4楼-- · 2019-03-31 03:00

To obtain this sort of information, we override new/delete and malloc/free, providing our own heap implementations that store stacktraces on allocation and produce a report when the heap is destroyed (as well as adding sentinels to detect buffer overruns).

This is a fair bit of work the first time you do it. This guy has written a freeware tool that handles all the hard bits - I have not tried it out myself, but his explanation of how he wrote it is useful when rolling your own.

查看更多
我欲成王,谁敢阻挡
5楼-- · 2019-03-31 03:03

I played around with the CRT Debug Heap functions Mike B pointed out, but ultimately I wasn't satisfied just getting the address of the leaked memory. Getting the stacks like UMDH provides makes debugging so much faster. So, in my main() function now I launch UMDH using CreateProcess before and after I run the tests to take heap snapshots. I also wrote a trivial batch file that runs my test harness and then diffs the heap snapshots. So, I launch the batch file and get my test results and a text file with the full stacks of any unfreed allocations all in one shot.

UMDH picks up a lot of false positives, so perhaps some hybrid of the CrtDebug stuff and what I'm doing now would be a better solution. But for right now I'm happy with what I've got.

Now if I just had a way to detect if I was not closing any handles...

查看更多
Bombasti
6楼-- · 2019-03-31 03:05

You can define DEBUG_NEW and that turns on some leak detection, you need to define it before including any system include files. It only checks for leaks using the new operator and of course you must recompile your code so you can't attach it like valgrind.

See more info here:

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

查看更多
登录 后发表回答