summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAliaksey Kandratsenka <alk@tut.by>2014-01-11 12:46:02 -0800
committerAliaksey Kandratsenka <alk@tut.by>2014-01-18 14:14:22 -0800
commit185bf3fcc36f8cb3839abdfe652f615bfb5306d1 (patch)
tree2a121bb684087cb44ff7526c43887547a54a96ee
parent48a0d131c1aa088c6075e9c4676ee430f81d8600 (diff)
downloadgperftools-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.cc12
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);
}
});