From dd3d9d969e9b889e96c2af497e436856fac1a2a7 Mon Sep 17 00:00:00 2001 From: csilvers Date: Tue, 8 Feb 2011 01:03:37 +0000 Subject: [PATCH] * Fix tcmalloc_unittest on MSVC 10 in release mode (csilvers) * Fix malloc_hook_c.h to compile with -ansi under gcc (csilvers) git-svn-id: http://gperftools.googlecode.com/svn/trunk@104 6b5cf1ce-ec42-a296-1ba9-69fdba395a50 --- NEWS | 13 ++++++++++++- src/google/malloc_hook_c.h | 10 +++++++++- src/tests/tcmalloc_unittest.cc | 24 +++++++++++++++++++++++- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 741e1f8..62a2f62 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,15 @@ -== 04 February 2011 == +== 7 February 2011 == + +Thanks to endlessr..., who +[http://code.google.com/p/google-perftools/issues/detail?id=307 identified] +why some tests were failing under MSVC 10 in release mode. It does not look +like these failures point toward any problem with tcmalloc itself; rather, the +problem is with the test, which made some assumptions that broke under the +some aggressive optimizations used in MSVC 10. I'll fix the test, but in +the meantime, feel free to use perftools even when compiled under MSVC +10. + +== 4 February 2011 == I've just released perftools 1.7 diff --git a/src/google/malloc_hook_c.h b/src/google/malloc_hook_c.h index d19e649..51ccc95 100644 --- a/src/google/malloc_hook_c.h +++ b/src/google/malloc_hook_c.h @@ -40,7 +40,7 @@ #include #include -// Annoying stuff for windows -- makes sure clients can import these functions +/* Annoying stuff for windows; makes sure clients can import these functions */ #ifndef PERFTOOLS_DLL_DECL # ifdef _WIN32 # define PERFTOOLS_DLL_DECL __declspec(dllimport) @@ -49,6 +49,10 @@ # endif #endif +#ifdef __cplusplus +extern "C" { +#endif + /* Get the current stack trace. Try to skip all routines up to and * and including the caller of MallocHook::Invoke*. * Use "skip_count" (similarly to GetStackTrace from stacktrace.h) @@ -108,4 +112,8 @@ typedef void (*MallocHook_SbrkHook)(const void* result, ptrdiff_t increment); PERFTOOLS_DLL_DECL MallocHook_SbrkHook MallocHook_SetSbrkHook(MallocHook_SbrkHook hook); +#ifdef __cplusplus +} // extern "C" +#endif + #endif /* _MALLOC_HOOK_C_H_ */ diff --git a/src/tests/tcmalloc_unittest.cc b/src/tests/tcmalloc_unittest.cc index 284e848..7c21fc4 100644 --- a/src/tests/tcmalloc_unittest.cc +++ b/src/tests/tcmalloc_unittest.cc @@ -871,7 +871,10 @@ static void TestReleaseToSystem() { #endif // #ifndef DEBUGALLOCATION } -bool g_no_memory = false; +// On MSVC10, in release mode, the optimizer convinces itself +// g_no_memory is never changed (I guess it doesn't realize OnNoMemory +// might be called). Work around this by setting the var volatile. +volatile bool g_no_memory = false; std::new_handler g_old_handler = NULL; static void OnNoMemory() { g_no_memory = true; @@ -999,6 +1002,7 @@ static int RunAllTests(int argc, char** argv) { SetDeleteHook(); // ditto void* p1 = malloc(10); + CHECK(p1 != NULL); // force use of this variable VerifyNewHookWasCalled(); // Also test the non-standard tc_malloc_size size_t actual_p1_size = tc_malloc_size(p1); @@ -1009,19 +1013,23 @@ static int RunAllTests(int argc, char** argv) { p1 = calloc(10, 2); + CHECK(p1 != NULL); VerifyNewHookWasCalled(); p1 = realloc(p1, 30); + CHECK(p1 != NULL); VerifyNewHookWasCalled(); VerifyDeleteHookWasCalled(); cfree(p1); // synonym for free VerifyDeleteHookWasCalled(); CHECK_EQ(posix_memalign(&p1, sizeof(p1), 40), 0); + CHECK(p1 != NULL); VerifyNewHookWasCalled(); free(p1); VerifyDeleteHookWasCalled(); p1 = memalign(sizeof(p1) * 2, 50); + CHECK(p1 != NULL); VerifyNewHookWasCalled(); free(p1); VerifyDeleteHookWasCalled(); @@ -1035,43 +1043,51 @@ static int RunAllTests(int argc, char** argv) { #endif p1 = valloc(60); + CHECK(p1 != NULL); VerifyNewHookWasCalled(); free(p1); VerifyDeleteHookWasCalled(); p1 = pvalloc(70); + CHECK(p1 != NULL); VerifyNewHookWasCalled(); free(p1); VerifyDeleteHookWasCalled(); char* p2 = new char; + CHECK(p2 != NULL); VerifyNewHookWasCalled(); delete p2; VerifyDeleteHookWasCalled(); p2 = new char[100]; + CHECK(p2 != NULL); VerifyNewHookWasCalled(); delete[] p2; VerifyDeleteHookWasCalled(); p2 = new(std::nothrow) char; + CHECK(p2 != NULL); VerifyNewHookWasCalled(); delete p2; VerifyDeleteHookWasCalled(); p2 = new(std::nothrow) char[100]; + CHECK(p2 != NULL); VerifyNewHookWasCalled(); delete[] p2; VerifyDeleteHookWasCalled(); // Another way of calling operator new p2 = static_cast(::operator new(100)); + CHECK(p2 != NULL); VerifyNewHookWasCalled(); ::operator delete(p2); VerifyDeleteHookWasCalled(); // Try to call nothrow's delete too. Compilers use this. p2 = static_cast(::operator new(100, std::nothrow)); + CHECK(p2 != NULL); VerifyNewHookWasCalled(); ::operator delete(p2, std::nothrow); VerifyDeleteHookWasCalled(); @@ -1087,8 +1103,10 @@ static int RunAllTests(int argc, char** argv) { int size = 8192*2; p1 = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + CHECK(p1 != NULL); VerifyMmapHookWasCalled(); p1 = mremap(p1, size, size/2, 0); + CHECK(p1 != NULL); VerifyMremapHookWasCalled(); size /= 2; munmap(p1, size); @@ -1097,6 +1115,7 @@ static int RunAllTests(int argc, char** argv) { int fd = open("/dev/zero", O_RDONLY); CHECK_GE(fd, 0); // make sure the open succeeded p1 = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0); + CHECK(p1 != NULL); VerifyMmapHookWasCalled(); munmap(p1, 8192); VerifyMunmapHookWasCalled(); @@ -1115,11 +1134,14 @@ static int RunAllTests(int argc, char** argv) { #if defined(HAVE_SBRK) && defined(__linux) && \ (defined(__i386__) || defined(__x86_64__)) p1 = sbrk(8192); + CHECK(p1 != NULL); VerifySbrkHookWasCalled(); p1 = sbrk(-8192); + CHECK(p1 != NULL); VerifySbrkHookWasCalled(); // However, sbrk hook should *not* be called with sbrk(0) p1 = sbrk(0); + CHECK(p1 != NULL); CHECK_EQ(g_SbrkHook_calls, 0); #else // this is just to quiet the compiler: make sure all fns are called IncrementCallsToSbrkHook();