finding memory leaks in a boost::test::unit_test

user206705 picture user206705 · Mar 11, 2011 · Viewed 7.9k times · Source

This question is a continuation to a previous question on boost::test::unit_test.

I've written a unit test and built the unit test. Here's the build output:

    2>------ Build started: Project: UnitTests, Configuration: Debug Win32 ------
2>  stdafx.cpp
2>  UnitTests.cpp
2>  UnitTests.vcxproj -> F:\Src\Crash\trunk\Debug\UnitTests.exe
2>  
2>  Running 3 test cases...
2>  Test suite "Master Test Suite" passed with:
2>    3 assertions out of 3 passed
2>    3 test cases out of 3 passed
2>  
2>  Detected memory leaks!
2>  Dumping objects ->
2>  {810} normal block at 0x007C5610, 8 bytes long.
2>   Data: <P C     > 50 E3 43 00 00 00 00 00 
2>  {809} normal block at 0x0043E350, 32 bytes long.
2>   Data: < V|             > 10 56 7C 00 00 00 CD CD CD CD CD CD CD CD CD CD 
2>  Object dump complete.

I know from experience that the output that describes the memory leak is from use of the CRT memory leak detection.

Normally, to detect where the allocations are in source code, you might add the following to the start of your entry point:

_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
_CrtSetBreakAlloc( 809 );

However, boost::test::unit_test defines its own entry point, preventing me from adding these lines. I've tried adding these lines to a fixture, but without success. I've also tried adding these lines inside the test code, again without success. When I try these modifications, I get the following output:

1>------ Build started: Project: UnitTests, Configuration: Debug Win32 ------
1>  UnitTests.cpp
1>  UnitTests.vcxproj -> F:\Src\Crash\trunk\Debug\UnitTests.exe
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: The command ""F:\Src\Crash\trunk\Debug\\UnitTests.exe" --result_code=no --report_level=short
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: :VCEnd" exited with code -2147483645.

That -ve number translates to 0x80000003 (one or more arguments are invalid).

Can anyone suggest how I might detect where in my source code / tests these two memory leaks might be?

For the curious, here's my test:

void DShowUtilsGetFilter()
{
    // SysDevNames is a typedef for std::vector<wstring*>
    using namespace Crash::DirectShow;
    using namespace Crash::SystemDevices;
    using namespace std;

    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    _CrtSetBreakAlloc( 809 );

    HRESULT                 hr  = S_OK; 
    SysDevNames             AudioDevices;
    wstring                 wsAudioDevice;  
    CComPtr <IBaseFilter>   spAudioFilter;

    try
    {
        TFAIL( ListDevicesInCategory( CLSID_AudioCompressorCategory, AudioDevices ) );

        if( AudioDevices.size() == 0 )
            throw E_FAIL;

        wsAudioDevice.assign(*AudioDevices.at(0));

        TFAIL( GetFilter( CLSID_AudioCompressorCategory, wsAudioDevice, &spAudioFilter ) );

        if( spAudioFilter.p )
            spAudioFilter.Release();

        BOOST_CHECK_EQUAL (hr, S_OK);

    }
    catch(...)
    {
        BOOST_CHECK_EQUAL( 1, 0 );              
    }


    if( AudioDevices.size() > 0)
    {
        for(SysDevNamesItr itr = AudioDevices.begin(); itr != AudioDevices.end(); itr ++ )
            delete *itr;

        AudioDevices.clear();
    }
}

Answer

Nick picture Nick · Mar 11, 2011

Have a look here: http://www.boost.org/doc/libs/1_40_0/libs/test/doc/html/execution-monitor/user-guide.html

You can probably set a command line argument to break at the required allocation ID.

Edit: use --detect_memory_leak on the command line (from here: http://www.boost.org/doc/libs/1_40_0/libs/test/doc/html/utf/user-guide/runtime-config/reference.html )