MB-20586: ep_unit_tests: Use real memory tracking code 42/67442/2
authorDave Rigby <daver@couchbase.com>
Fri, 12 Aug 2016 14:08:39 +0000 (15:08 +0100)
committerDave Rigby <daver@couchbase.com>
Thu, 8 Sep 2016 10:11:43 +0000 (10:11 +0000)
Use the 'real' memory tracking hooks instead of alloc_hooks_dummy in
the ep-engine unit tests. This more accurately reflects how our code
used in the 'real world'

Change-Id: I231a179e7765d46a63c72686c0279983db21cf0b
Reviewed-on: http://review.couchbase.org/67442
Well-Formed: buildbot <build@couchbase.com>
Tested-by: buildbot <build@couchbase.com>
Reviewed-by: Jim Walker <jim@couchbase.com>
CMakeLists.txt
tests/module_tests/ep_unit_tests_main.cc

index 3319910..322e76f 100644 (file)
@@ -239,9 +239,10 @@ ADD_EXECUTABLE(ep-engine_ep_unit_tests
   ${KVSTORE_SOURCE}
   ${COUCH_KVSTORE_SOURCE}
   ${FOREST_KVSTORE_SOURCE}
-  ${Memcached_SOURCE_DIR}/daemon/alloc_hooks_dummy.cc
+  $<TARGET_OBJECTS:memory_tracking>
   ${Memcached_SOURCE_DIR}/programs/engine_testapp/mock_server.cc)
-TARGET_LINK_LIBRARIES(ep-engine_ep_unit_tests couchstore cJSON dirutils forestdb gtest JSON_checker mcd_util platform)
+TARGET_LINK_LIBRARIES(ep-engine_ep_unit_tests couchstore cJSON dirutils forestdb gtest JSON_checker mcd_util platform
+                      ${MALLOC_LIBRARIES})
 
 ADD_EXECUTABLE(ep-engine_atomic_ptr_test
   tests/module_tests/atomic_ptr_test.cc
index 810736f..c375743 100644 (file)
 /* static storage for environment variable set by putenv(). */
 static char allow_no_stats_env[] = "ALLOW_NO_STATS_UPDATE=yeah";
 
+#ifdef HAVE_JEMALLOC
+/* Global replacement of operators new and delete when using jemalloc.
+ *
+ * This isn't needed for functionality reasons (the code works
+ * correctly without these), but to improve interoperability with
+ * Valgrind. The issue encountered is that without these replacements,
+ * the application will call the standard symbols in libstdc++, which
+ * Valgrind intercepts, and replaces with it's own implementation
+ * (which doesn't call 'our' je_malloc). As a consequence when the
+ * memory tracking code (objectregistery.cc) later calls
+ * je_malloc_usable_size() on the returned pointer from Valgrind's
+ * operator new, we encounter invalid memory accesses as jemalloc is
+ * trying to introspect a non-jemalloc allocation.
+ *
+ * By replacing operator new/delete in the executable program, we call
+ * our own malloc/free (see alloc_hooks.c) which directly call
+ * jemalloc.  Note that Valgrind reporting still works, as je_malloc
+ * is able to detect which running in Valgrind and makes the
+ * appropriate calls to Valgrind to inform it of allocations / frees.
+ */
+void* operator new(std::size_t count ) {
+    return malloc(count);
+}
+
+void operator delete(void* ptr ) noexcept
+{
+    free(ptr);
+}
+#endif // HAVE_JEMALLOC
+
 int main(int argc, char **argv) {
     bool log_to_stderr = false;
     // Parse command-line options.
@@ -55,6 +85,7 @@ int main(int argc, char **argv) {
 
     putenv(allow_no_stats_env);
 
+    mock_init_alloc_hooks();
     init_mock_server(log_to_stderr);
 
     if (memcached_initialize_stderr_logger(get_mock_server_api) != EXTENSION_SUCCESS) {