diff options
author | Aliaksey Kandratsenka <alk@tut.by> | 2014-01-11 12:46:02 -0800 |
---|---|---|
committer | Aliaksey Kandratsenka <alk@tut.by> | 2014-01-18 14:14:22 -0800 |
commit | 185bf3fcc36f8cb3839abdfe652f615bfb5306d1 (patch) | |
tree | 2a121bb684087cb44ff7526c43887547a54a96ee | |
parent | 48a0d131c1aa088c6075e9c4676ee430f81d8600 (diff) | |
download | gperftools-185bf3fcc36f8cb3839abdfe652f615bfb5306d1.tar.gz |
issue-581: avoid destructing DebugMallocImplementation
Because otherwise destructor might be invoked well before other places
that might touch malloc extension instance.
We're using placement new to initialize it and pass pointer to
MallocExtension::Register. Which ensures that destructor for it is
never run.
Based on idea suggested by Andrew C. Morrow.
-rw-r--r-- | src/debugallocation.cc | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/src/debugallocation.cc b/src/debugallocation.cc index 912b9f5..23cb019 100644 --- a/src/debugallocation.cc +++ b/src/debugallocation.cc @@ -1076,14 +1076,22 @@ class DebugMallocImplementation : public TCMallocImplementation { }; -static DebugMallocImplementation debug_malloc_implementation; +static union { + char chars[sizeof(DebugMallocImplementation)]; + void *ptr; +} debug_malloc_implementation_space; REGISTER_MODULE_INITIALIZER(debugallocation, { +#if (__cplusplus >= 201103L) + RAW_CHECK(alignof(debug_malloc_implementation_space) >= alignof(DebugMallocImplementation), + "debug_malloc_implementation_space is not properly aligned"); +#endif // Either we or valgrind will control memory management. We // register our extension if we're the winner. Otherwise let // Valgrind use its own malloc (so don't register our extension). if (!RunningOnValgrind()) { - MallocExtension::Register(&debug_malloc_implementation); + DebugMallocImplementation *impl = new (debug_malloc_implementation_space.chars) DebugMallocImplementation(); + MallocExtension::Register(impl); } }); |