0

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?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Bob
  • 4,576
  • 7
  • 39
  • 107
  • 2
    It would help if you would show the actual code. It sounds like maybe cpputest is checking for memory leaks *before* the allocated memory is freed, whereas valgrind is checking for leaks *after* the memory is freed. – Remy Lebeau May 25 '23 at 20:31
  • 1
    what does `--show-leak-kinds=all` show? – underloaded_operator May 25 '23 at 20:31
  • @RemyLebeau shared the code but I also changed/simplified the problem. – Bob May 26 '23 at 19:15
  • The leak report is complaining about a mismatch in dynamic memory, but your code is not allocating any memory dynamically, so logically it would have to be a problem with the framework or the leak reporter. – Remy Lebeau May 26 '23 at 19:22
  • @RemyLebeau I agree. The problem is that when I introduce `valgrind`, in addition to `valgrind` reporting an error, `cpputest` also reports a memory leak. So the overridden memory functions that `cpputest` uses are affected by valgrind. – Bob May 26 '23 at 19:26

1 Answers1

0

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.

Bob
  • 4,576
  • 7
  • 39
  • 107