cpputest: Valgrind mismatch new/delete

Hi, I use CppUTest for a personal project and I get many valgrind error. I try to reproduce these errors with the smallest possible test and I get the following code:

#include <CppUTest/TestHarness.h>
#include <CppUTest/CommandLineTestRunner.h>

TEST_GROUP(MyGroup)
{
};

int main(int argc, char *argv[])
{
    return CommandLineTestRunner::RunAllTests(argc, argv);
}

After compiling, I run test thought valgrind and I get the following output:

/usr/bin/valgrind --tool=memcheck --leak-check=full --show-reachable=no --und
ef-value-errors=yes --track-origins=yes ./test
==14181== Memcheck, a memory error detector
==14181== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==14181== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==14181== Command: ./test
==14181==

OK (0 tests, 0 ran, 0 checks, 0 ignored, 0 filtered out, 1 ms)

==14181== Mismatched free() / delete / delete []
==14181==    at 0x4C2BD3A: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14181==    by 0x404227: normal_operator_delete(void*) (MemoryLeakWarningPlugin.cpp:285)
==14181==    by 0x4042F8: operator delete(void*, unsigned long) (MemoryLeakWarningPlugin.cpp:324)
==14181==    by 0x41636C: MemoryLeakDetector::~MemoryLeakDetector() (MemoryLeakDetector.cpp:434)
==14181==    by 0x40475B: MemoryLeakWarningPlugin::destroyGlobalDetector() (MemoryLeakWarningPlugin.cpp:504)
==14181==    by 0x4048CB: MemoryLeakWarningPlugin::~MemoryLeakWarningPlugin() (MemoryLeakWarningPlugin.cpp:547)
==14181==    by 0x401680: CommandLineTestRunner::RunAllTests(int, char const**) (CommandLineTestRunner.cpp:45)
==14181==    by 0x401527: CommandLineTestRunner::RunAllTests(int, char**) (CommandLineTestRunner.cpp:37)
==14181==    by 0x401505: main (test.cpp:10)
==14181==  Address 0x5a89de0 is 0 bytes inside a block of size 4,744 alloc'd
==14181==    at 0x4C2B1EC: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14181==    by 0x404685: MemoryLeakWarningPlugin::getGlobalDetector() (MemoryLeakWarningPlugin.cpp:478)
==14181==    by 0x40485F: MemoryLeakWarningPlugin::MemoryLeakWarningPlugin(SimpleString const&, MemoryLeakDetector*) (MemoryLeakWarningPlugin.cpp:538)
==14181==    by 0x401583: CommandLineTestRunner::RunAllTests(int, char const**) (CommandLineTestRunner.cpp:45)
==14181==    by 0x401527: CommandLineTestRunner::RunAllTests(int, char**) (CommandLineTestRunner.cpp:37)
==14181==    by 0x401505: main (test.cpp:10)
==14181==
==14181== Mismatched free() / delete / delete []
==14181==    at 0x4C2BD3A: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14181==    by 0x404227: normal_operator_delete(void*) (MemoryLeakWarningPlugin.cpp:285)
==14181==    by 0x4042F8: operator delete(void*, unsigned long) (MemoryLeakWarningPlugin.cpp:324)
==14181==    by 0x404C36: MemoryLeakWarningReporter::~MemoryLeakWarningReporter() (MemoryLeakWarningPlugin.cpp:459)
==14181==    by 0x404784: MemoryLeakWarningPlugin::destroyGlobalDetector() (MemoryLeakWarningPlugin.cpp:505)
==14181==    by 0x4048CB: MemoryLeakWarningPlugin::~MemoryLeakWarningPlugin() (MemoryLeakWarningPlugin.cpp:547)
==14181==    by 0x401680: CommandLineTestRunner::RunAllTests(int, char const**) (CommandLineTestRunner.cpp:45)
==14181==    by 0x401527: CommandLineTestRunner::RunAllTests(int, char**) (CommandLineTestRunner.cpp:37)
==14181==    by 0x401505: main (test.cpp:10)
==14181==  Address 0x5a89d90 is 0 bytes inside a block of size 8 alloc'd
==14181==    at 0x4C2B1EC: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14181==    by 0x404669: MemoryLeakWarningPlugin::getGlobalDetector() (MemoryLeakWarningPlugin.cpp:477)
==14181==    by 0x40485F: MemoryLeakWarningPlugin::MemoryLeakWarningPlugin(SimpleString const&, MemoryLeakDetector*) (MemoryLeakWarningPlugin.cpp:538)
==14181==    by 0x401583: CommandLineTestRunner::RunAllTests(int, char const**) (CommandLineTestRunner.cpp:45)
==14181==    by 0x401527: CommandLineTestRunner::RunAllTests(int, char**) (CommandLineTestRunner.cpp:37)
==14181==    by 0x401505: main (test.cpp:10)
==14181==
==14181==
==14181== HEAP SUMMARY:
==14181==     in use at exit: 0 bytes in 0 blocks
==14181==   total heap usage: 46 allocs, 46 frees, 78,924 bytes allocated
==14181==
==14181== All heap blocks were freed -- no leaks are possible
==14181==
==14181== For counts of detected and suppressed errors, rerun with: -v
==14181== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

I try to analyse error, and it seems to be related to allocation and deallocation of global memory leak reporter and detector. They were allocated by new and free with delete both… I try to overload new and delete operator in MemoryLeakWarningReporter (see following patch) and test result show only one error.

diff --git a/src/CppUTest/MemoryLeakWarningPlugin.cpp b/src/CppUTest/MemoryLeakWarningPlugin.cpp
index 00d6e164..c26f3a0f 100644
--- a/src/CppUTest/MemoryLeakWarningPlugin.cpp
+++ b/src/CppUTest/MemoryLeakWarningPlugin.cpp
@@ -463,6 +463,16 @@ public:
         UtestShell* currentTest = UtestShell::getCurrent();
         currentTest->failWith(FailFailure(currentTest, currentTest->getName().asCharString(), currentTest->getLineNumber(), fail_string), TestTerminatorWithoutExceptions());
     } // LCOV_EXCL_LINE
+
+    static void operator delete(void *ptr)
+    {
+        free(ptr);
+    }
+
+    void *operator new(std::size_t size)
+    {
+        return malloc(size);
+    }
 };

 static MemoryLeakFailure* globalReporter = 0;

So, I think there is a little issue in New and Delete overload but I did not have time to dig in it yet. Or Valgrind report virtual error!

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 27 (18 by maintainers)

Commits related to this issue

Most upvoted comments

No, we disabled the memcheck feature of cpputest and do use valgrind instead for the assertion.

@offa Somehow I remember having bumped into this issue before and remembered it had to do with the compiler and valgrind. Its ok to keep it open and see if we can find a better solution.

Ok, so I get no error when I compile CppUTest with CMake… I see some difference on my system: When I use CMake, I get these flags (I clean warning flags…):

CppUTest CFLAGS:                     
-include "<path_to_cpputest>/include/CppUTest/MemoryLeakDetectorMallocMacros.h"
-pedantic

CppUTest CXXFLAGS:
-include "<path_to_cpputest>/include/CppUTest/MemoryLeakDetectorNewMacros.h"
-include "<path_to_cpputest>/include/CppUTest/MemoryLeakDetectorMallocMacros.h"    
-pedantic

whereas with autotools, I get:

Default CFLAGS:
-g -O2

Default CXXFLAGS:
-g -O2

CppUTest CFLAGS:
-pedantic

   CppUTest CXXFLAGS:                    
-std=c++11
-include ./include/CppUTest/MemoryLeakDetectorNewMacros.h
-pedantic

CppUTest CPPFLAGS
-include ./include/CppUTest/MemoryLeakDetectorMallocMacros.h
-I ./include

So, main differences are, with autotools, I do not have a -include option in CFLAGS and -std=c++11 is added. Same for -O2 and -g (which, to be honest, I do not know from where they come)