Search code examples
c++memory-leaksvalgrindcpputest

cpputest/valgrind - memory leak indicator inconsistent


I'm forced to use cpputest and I want to know if its memory leak detector is useful.

As of now, it seems to be garbage.

main.cpp:

#include <iostream>

#include "CppUTest/CommandLineTestRunner.h"

int main(int argc, char** argv)
{
    int ret = 0;
    ret = CommandLineTestRunner::RunAllTests(argc, argv);
    return ret;
}

test.cpp

#include <string>
#include "TestHarness.h"

TEST_GROUP(Detector)
{
    
    void setup()
    {
    }

    void teardown()
    {
    }
};

TEST(Detector, test_GetName)
{   

    std::string ret;
}

Run 1:

$ ./HostUnitTest
.
OK (1 tests, 1 ran, 0 checks, 0 ignored, 0 filtered out, 0 ms)

But then when I run it with valgrind, valgrind complains and cpputest complains of a memory leak:

$ valgrind  ./HostUnitTest |& tee valgrind.log

The output is 1000 lines but here are first few:

==15731== Memcheck, a memory error detector
==15731== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==15731== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==15731== Command: ./HostUnitTest
==15731== 
==15731== Mismatched free() / delete / delete []
==15731==    at 0x484BB6F: operator delete(void*, unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==15731==    by 0x110C4C: TEST_Detector_test_GetName_Test::~TEST_Detector_test_GetName_Test() (DetectorSerialDevice_test.cpp:19)
==15731==    by 0x1255CB: UtestShell::destroyTest(Utest*) (in /mnt/c/work/project/product/tests/hosts/build/HostUnitTest)
==15731==    by 0x1257AA: UtestShell::runOneTestInCurrentProcess(TestPlugin*, TestResult&) (in /mnt/c/work/project/product/tests/hosts/build/HostUnitTest)
==15731==    by 0x12520D: helperDoRunOneTestInCurrentProcess (in /mnt/c/work/project/product/tests/hosts/build/HostUnitTest)
==15731==    by 0x129ACF: PlatformSpecificSetJmpImplementation (in /mnt/c/work/project/product/tests/hosts/build/HostUnitTest)
==15731==    by 0x12554A: UtestShell::runOneTest(TestPlugin*, TestResult&) (in /mnt/c/work/project/product/tests/hosts/build/HostUnitTest)
==15731==    by 0x12C7C6: TestRegistry::runAllTests(TestResult&) (in /mnt/c/work/project/product/tests/hosts/build/HostUnitTest)
==15731==    by 0x1137FD: CommandLineTestRunner::runAllTests() (in /mnt/c/work/project/product/tests/hosts/build/HostUnitTest)
==15731==    by 0x113262: CommandLineTestRunner::runAllTestsMain() (in /mnt/c/work/project/product/tests/hosts/build/HostUnitTest)
==15731==    by 0x112F1D: CommandLineTestRunner::RunAllTests(int, char const* const*) (in /mnt/c/work/project/product/tests/hosts/build/HostUnitTest)
==15731==    by 0x112E41: CommandLineTestRunner::RunAllTests(int, char**) (in /mnt/c/work/project/product/tests/hosts/build/HostUnitTest)

And in that link is the following fail message from cpputest:

/mnt/c/work/project/product/tests/hosts/unit_tests/DetectorSerialDevice_test.cpp:19: error: Failure in TEST(Detector, test_GetName)
    Memory leak(s) found.
Alloc num (3) Leak size: 8 Allocated at: /mnt/c/work/project/product/tests/hosts/unit_tests/DetectorSerialDevice_test.cpp and line: 19. Type: "new"
    Memory: <0x4dd63c0> Content:
    0000: 18 dc 13 00 00 00 00 00                          |........|
Total number of leaks:  1

But why run the unit tests with valgrind?
Well I don't need to but there's another problem with cpputest - see the history of this question - and in order to solve that problem, I need to solve this simpler one.

QUESTION
Is this a known issue of cpputest?


Solution

  • The problem is static variables.

    When I initialize my object inside my test case, cpputest detects any memory initializations that occur when my constructor calls another class' methods.

    The other class has a static variable.

    But when my test-case ends, that static variable does not get released so cpputest flags that as a memory leak.

    Leaving the context of my test case doesn't trigger the destructor of the static variable because only the program exiting triggers that.

    Solution

    I will disable cpputest's memory checking and use valgrind and I will run the cpputest executable one test per execution so that static state doesn't propagate between test cases.