* 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
This commit is contained in:
csilvers 2011-02-08 01:03:37 +00:00
parent 7375b4f3cb
commit dd3d9d969e
3 changed files with 44 additions and 3 deletions

13
NEWS
View File

@ -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 I've just released perftools 1.7

View File

@ -40,7 +40,7 @@
#include <stddef.h> #include <stddef.h>
#include <sys/types.h> #include <sys/types.h>
// 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 #ifndef PERFTOOLS_DLL_DECL
# ifdef _WIN32 # ifdef _WIN32
# define PERFTOOLS_DLL_DECL __declspec(dllimport) # define PERFTOOLS_DLL_DECL __declspec(dllimport)
@ -49,6 +49,10 @@
# endif # endif
#endif #endif
#ifdef __cplusplus
extern "C" {
#endif
/* Get the current stack trace. Try to skip all routines up to and /* Get the current stack trace. Try to skip all routines up to and
* and including the caller of MallocHook::Invoke*. * and including the caller of MallocHook::Invoke*.
* Use "skip_count" (similarly to GetStackTrace from stacktrace.h) * 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 PERFTOOLS_DLL_DECL
MallocHook_SbrkHook MallocHook_SetSbrkHook(MallocHook_SbrkHook hook); MallocHook_SbrkHook MallocHook_SetSbrkHook(MallocHook_SbrkHook hook);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* _MALLOC_HOOK_C_H_ */ #endif /* _MALLOC_HOOK_C_H_ */

View File

@ -871,7 +871,10 @@ static void TestReleaseToSystem() {
#endif // #ifndef DEBUGALLOCATION #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; std::new_handler g_old_handler = NULL;
static void OnNoMemory() { static void OnNoMemory() {
g_no_memory = true; g_no_memory = true;
@ -999,6 +1002,7 @@ static int RunAllTests(int argc, char** argv) {
SetDeleteHook(); // ditto SetDeleteHook(); // ditto
void* p1 = malloc(10); void* p1 = malloc(10);
CHECK(p1 != NULL); // force use of this variable
VerifyNewHookWasCalled(); VerifyNewHookWasCalled();
// Also test the non-standard tc_malloc_size // Also test the non-standard tc_malloc_size
size_t actual_p1_size = tc_malloc_size(p1); size_t actual_p1_size = tc_malloc_size(p1);
@ -1009,19 +1013,23 @@ static int RunAllTests(int argc, char** argv) {
p1 = calloc(10, 2); p1 = calloc(10, 2);
CHECK(p1 != NULL);
VerifyNewHookWasCalled(); VerifyNewHookWasCalled();
p1 = realloc(p1, 30); p1 = realloc(p1, 30);
CHECK(p1 != NULL);
VerifyNewHookWasCalled(); VerifyNewHookWasCalled();
VerifyDeleteHookWasCalled(); VerifyDeleteHookWasCalled();
cfree(p1); // synonym for free cfree(p1); // synonym for free
VerifyDeleteHookWasCalled(); VerifyDeleteHookWasCalled();
CHECK_EQ(posix_memalign(&p1, sizeof(p1), 40), 0); CHECK_EQ(posix_memalign(&p1, sizeof(p1), 40), 0);
CHECK(p1 != NULL);
VerifyNewHookWasCalled(); VerifyNewHookWasCalled();
free(p1); free(p1);
VerifyDeleteHookWasCalled(); VerifyDeleteHookWasCalled();
p1 = memalign(sizeof(p1) * 2, 50); p1 = memalign(sizeof(p1) * 2, 50);
CHECK(p1 != NULL);
VerifyNewHookWasCalled(); VerifyNewHookWasCalled();
free(p1); free(p1);
VerifyDeleteHookWasCalled(); VerifyDeleteHookWasCalled();
@ -1035,43 +1043,51 @@ static int RunAllTests(int argc, char** argv) {
#endif #endif
p1 = valloc(60); p1 = valloc(60);
CHECK(p1 != NULL);
VerifyNewHookWasCalled(); VerifyNewHookWasCalled();
free(p1); free(p1);
VerifyDeleteHookWasCalled(); VerifyDeleteHookWasCalled();
p1 = pvalloc(70); p1 = pvalloc(70);
CHECK(p1 != NULL);
VerifyNewHookWasCalled(); VerifyNewHookWasCalled();
free(p1); free(p1);
VerifyDeleteHookWasCalled(); VerifyDeleteHookWasCalled();
char* p2 = new char; char* p2 = new char;
CHECK(p2 != NULL);
VerifyNewHookWasCalled(); VerifyNewHookWasCalled();
delete p2; delete p2;
VerifyDeleteHookWasCalled(); VerifyDeleteHookWasCalled();
p2 = new char[100]; p2 = new char[100];
CHECK(p2 != NULL);
VerifyNewHookWasCalled(); VerifyNewHookWasCalled();
delete[] p2; delete[] p2;
VerifyDeleteHookWasCalled(); VerifyDeleteHookWasCalled();
p2 = new(std::nothrow) char; p2 = new(std::nothrow) char;
CHECK(p2 != NULL);
VerifyNewHookWasCalled(); VerifyNewHookWasCalled();
delete p2; delete p2;
VerifyDeleteHookWasCalled(); VerifyDeleteHookWasCalled();
p2 = new(std::nothrow) char[100]; p2 = new(std::nothrow) char[100];
CHECK(p2 != NULL);
VerifyNewHookWasCalled(); VerifyNewHookWasCalled();
delete[] p2; delete[] p2;
VerifyDeleteHookWasCalled(); VerifyDeleteHookWasCalled();
// Another way of calling operator new // Another way of calling operator new
p2 = static_cast<char*>(::operator new(100)); p2 = static_cast<char*>(::operator new(100));
CHECK(p2 != NULL);
VerifyNewHookWasCalled(); VerifyNewHookWasCalled();
::operator delete(p2); ::operator delete(p2);
VerifyDeleteHookWasCalled(); VerifyDeleteHookWasCalled();
// Try to call nothrow's delete too. Compilers use this. // Try to call nothrow's delete too. Compilers use this.
p2 = static_cast<char*>(::operator new(100, std::nothrow)); p2 = static_cast<char*>(::operator new(100, std::nothrow));
CHECK(p2 != NULL);
VerifyNewHookWasCalled(); VerifyNewHookWasCalled();
::operator delete(p2, std::nothrow); ::operator delete(p2, std::nothrow);
VerifyDeleteHookWasCalled(); VerifyDeleteHookWasCalled();
@ -1087,8 +1103,10 @@ static int RunAllTests(int argc, char** argv) {
int size = 8192*2; int size = 8192*2;
p1 = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, p1 = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE,
-1, 0); -1, 0);
CHECK(p1 != NULL);
VerifyMmapHookWasCalled(); VerifyMmapHookWasCalled();
p1 = mremap(p1, size, size/2, 0); p1 = mremap(p1, size, size/2, 0);
CHECK(p1 != NULL);
VerifyMremapHookWasCalled(); VerifyMremapHookWasCalled();
size /= 2; size /= 2;
munmap(p1, size); munmap(p1, size);
@ -1097,6 +1115,7 @@ static int RunAllTests(int argc, char** argv) {
int fd = open("/dev/zero", O_RDONLY); int fd = open("/dev/zero", O_RDONLY);
CHECK_GE(fd, 0); // make sure the open succeeded CHECK_GE(fd, 0); // make sure the open succeeded
p1 = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0); p1 = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0);
CHECK(p1 != NULL);
VerifyMmapHookWasCalled(); VerifyMmapHookWasCalled();
munmap(p1, 8192); munmap(p1, 8192);
VerifyMunmapHookWasCalled(); VerifyMunmapHookWasCalled();
@ -1115,11 +1134,14 @@ static int RunAllTests(int argc, char** argv) {
#if defined(HAVE_SBRK) && defined(__linux) && \ #if defined(HAVE_SBRK) && defined(__linux) && \
(defined(__i386__) || defined(__x86_64__)) (defined(__i386__) || defined(__x86_64__))
p1 = sbrk(8192); p1 = sbrk(8192);
CHECK(p1 != NULL);
VerifySbrkHookWasCalled(); VerifySbrkHookWasCalled();
p1 = sbrk(-8192); p1 = sbrk(-8192);
CHECK(p1 != NULL);
VerifySbrkHookWasCalled(); VerifySbrkHookWasCalled();
// However, sbrk hook should *not* be called with sbrk(0) // However, sbrk hook should *not* be called with sbrk(0)
p1 = sbrk(0); p1 = sbrk(0);
CHECK(p1 != NULL);
CHECK_EQ(g_SbrkHook_calls, 0); CHECK_EQ(g_SbrkHook_calls, 0);
#else // this is just to quiet the compiler: make sure all fns are called #else // this is just to quiet the compiler: make sure all fns are called
IncrementCallsToSbrkHook(); IncrementCallsToSbrkHook();