fix 219156 support static malloc or alternate malloc lib (e.g. tcmalloc) with new...
authorphilippe <philippe@a5019735-40e9-0310-863c-91ae7b9d1cf9>
Fri, 11 May 2012 19:33:46 +0000 (19:33 +0000)
committerphilippe <philippe@a5019735-40e9-0310-863c-91ae7b9d1cf9>
Fri, 11 May 2012 19:33:46 +0000 (19:33 +0000)
* pub_tool_redir.h : define the prefix to be used for "soname synonym"
  place holder
* vg_replace_malloc.c : define synonym place holder for malloc related
  functions
* m_redir.c : when detecting a soname synonym place holder redir spec, search
  in clo_soname_synonyms if there is a synonym pattern.
  If yes, replace the soname pattern. If not, ignore the redir spec.
* various files: implement or document the new clo --soname-synonyms
* new test memcheck/tests/static_malloc.vgtest

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12559 a5019735-40e9-0310-863c-91ae7b9d1cf9

14 files changed:
NEWS
coregrind/m_main.c
coregrind/m_options.c
coregrind/m_redir.c
coregrind/m_replacemalloc/vg_replace_malloc.c
coregrind/pub_core_options.h
docs/xml/manual-core.xml
include/pub_tool_redir.h
memcheck/tests/Makefile.am
memcheck/tests/static_malloc.c [new file with mode: 0644]
memcheck/tests/static_malloc.stderr.exp [new file with mode: 0644]
memcheck/tests/static_malloc.vgtest [new file with mode: 0644]
none/tests/cmdline1.stdout.exp
none/tests/cmdline2.stdout.exp

diff --git a/NEWS b/NEWS
index d87487466ca73b749f7fc2b032d3ae7334691149..fef2b28a15b45461983658626840ef5d8b2b2039 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,17 +3,22 @@ Release 3.8.0 (????)
 
 * ================== PLATFORM CHANGES =================
 
-* Support for amd64 AES instructions (AESKEYGENASSIST, AESENC, AESENCLAST,
-  AESDEC, AESDECLAST, AESIMC).
+* Support for intel AES instructions (AESKEYGENASSIST, AESENC, AESENCLAST,
+  AESDEC, AESDECLAST, AESIMC). Only supported for 64 bit architecture.
 
 * ==================== TOOL CHANGES ====================
 
+* Massif
+  - Using the new option --soname-synonyms, Massif can now understand
+    a program using statically linked malloc or using alternative
+    malloc libraries (such as tcmalloc).
+
 * Memcheck:
 
   - The leak_check GDB server monitor command now can
     control the maximum nr of loss records to output.
 
-  - reduction of memory use for applications allocating
+  - Reduction of memory use for applications allocating
     many blocks and/or having many partially defined bytes.
 
   - Addition of GDB server monitor command 'block_list' that lists
@@ -22,15 +27,22 @@ Release 3.8.0 (????)
   - Addition of GDB server monitor command 'who_points_at' that lists
     the locations pointing at a block.
 
-  - if a redzone size > 0 is given, VALGRIND_MALLOCLIKE_BLOCK now
+  - If a redzone size > 0 is given, VALGRIND_MALLOCLIKE_BLOCK now
     will detect an invalid access of these redzones, by marking them
     noaccess.
 
+  - Using the new option --soname-synonyms, Memcheck can now understand
+    a program using statically linked malloc or using alternative
+    malloc libraries (such as tcmalloc).
+
 * ==================== OTHER CHANGES ====================
 
 * The C++ demangler has been updated so as to work well with C++ 
   compiled by up to at least g++ 4.6.
 
+* Replacement/wrapping can be made more flexible thanks to the new option
+  --soname-synonyms.
+
 * The new option --fair-sched allows to control the locking mechanism
   used by Valgrind. The locking mechanism influences the performance
   and scheduling of multithreaded applications (in particular
@@ -56,6 +68,7 @@ https://bugs.kde.org/show_bug.cgi?id=XXXXXX
 where XXXXXX is the bug number as listed below.
 
 197914  Building valgrind from svn now requires automake-1.10
+219156  Valgrind does not handle statically linked malloc or other malloc lib (e.g. tcmalloc) 
 247386  make perf does not run all performance tests
 270006  Valgrind scheduler unfair 
 270796  s390x: Removed broken support for the TS insn
index 89b7571b870f8480c629d11cc53b53947183c774..71065ce399777ddf463886ac2f7a9f065866e7b0 100644 (file)
@@ -187,6 +187,9 @@ static void usage_NORETURN ( Bool debug_help )
 "    --require-text-symbol=:sonamepattern:symbolpattern    abort run if the\n"
 "                              stated shared object doesn't have the stated\n"
 "                              text symbol.  Patterns can contain ? and *.\n"
+"    --soname-synonyms=syn1=pattern1,syn2=pattern2,... synonym soname\n"
+"                              patterns for some Valgrind wrapping\n"
+"                              or replacement (such as malloc replacement)\n"
 "\n";
 
    Char* usage2 = 
@@ -483,6 +486,7 @@ void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
                             VG_(clo_vgdb_shadow_registers)) {}
       else if VG_BOOL_CLO(arg, "--db-attach",      VG_(clo_db_attach)) {}
       else if VG_BOOL_CLO(arg, "--demangle",       VG_(clo_demangle)) {}
+      else if VG_STR_CLO (arg, "--soname-synonyms",VG_(clo_soname_synonyms)) {}
       else if VG_BOOL_CLO(arg, "--error-limit",    VG_(clo_error_limit)) {}
       else if VG_INT_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode)) {}
       else if VG_BOOL_CLO(arg, "--show-emwarns",   VG_(clo_show_emwarns)) {}
index df00193c84f0ea1c31a03afb00371a8fad69569d..ca186c01d47337a309d3cef930178526efb69fd2 100644 (file)
@@ -66,6 +66,7 @@ Bool   VG_(clo_stats)          = False;
 Bool   VG_(clo_xml)            = False;
 HChar* VG_(clo_xml_user_comment) = NULL;
 Bool   VG_(clo_demangle)       = True;
+HChar* VG_(clo_soname_synonyms)    = NULL;
 Bool   VG_(clo_trace_children) = False;
 HChar* VG_(clo_trace_children_skip) = NULL;
 HChar* VG_(clo_trace_children_skip_by_arg) = NULL;
index c7936b156791d70ed8222d6a4daa5cf4a8c0d525..fd24c1a025784c0581c5606277060416b7816f43 100644 (file)
@@ -367,6 +367,18 @@ static void free_symname_array ( UChar** names, UChar** twoslots )
       dinfo_free(names);
 }
 
+static HChar const* advance_to_equal ( HChar const* c ) {
+   while (*c && *c != '=') {
+      ++c;
+   }
+   return c;
+}
+static HChar const* advance_to_comma ( HChar const* c ) {
+   while (*c && *c != ',') {
+      ++c;
+   }
+   return c;
+}
 
 /* Notify m_redir of the arrival of a new DebugInfo.  This is fairly
    complex, but the net effect is to (1) add a new entry to the
@@ -516,6 +528,48 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi )
                the following loop, and complain at that point. */
             continue;
          }
+
+         if (0 == VG_(strncmp) (demangled_sopatt, 
+                                VG_SO_SYN_PREFIX, VG_SO_SYN_PREFIX_LEN)) {
+            /* This is a redirection for handling lib so synonyms. If we
+               have a matching lib synonym, then replace the sopatt.
+               Otherwise, just ignore this redirection spec. */
+
+            if (!VG_(clo_soname_synonyms))
+               continue; // No synonyms => skip the redir.
+
+            /* Search for a matching synonym=newname*/
+            SizeT const sopatt_syn_len 
+               = VG_(strlen)(demangled_sopatt+VG_SO_SYN_PREFIX_LEN);
+            HChar const* last = VG_(clo_soname_synonyms);
+            
+            while (*last) {
+               HChar const* first = last;
+               last = advance_to_equal(first);
+               
+               if ((last - first) == sopatt_syn_len
+                   && 0 == VG_(strncmp)(demangled_sopatt+VG_SO_SYN_PREFIX_LEN,
+                                        first,
+                                        sopatt_syn_len)) {
+                  // Found the demangle_sopatt synonym => replace it
+                  first = last + 1;
+                  last = advance_to_comma(first);
+                  VG_(strncpy)(demangled_sopatt, first, last - first);
+                  demangled_sopatt[last - first] = '\0';
+                  break;
+               }
+
+               last = advance_to_comma(last);
+               if (*last == ',')
+                  last++;
+            }
+            
+            // If we have not replaced the sopatt, then skip the redir.
+            if (0 == VG_(strncmp) (demangled_sopatt, 
+                                   VG_SO_SYN_PREFIX, VG_SO_SYN_PREFIX_LEN))
+               continue;
+         }
+
          spec = dinfo_zalloc("redir.rnnD.1", sizeof(Spec));
          vg_assert(spec);
          spec->from_sopatt = dinfo_strdup("redir.rnnD.2", demangled_sopatt);
index a0d3d874bb49fc21c465d2960a508556e568e7e6..bec413aa485cb60938207f05d140c62b03c6c3ab 100644 (file)
@@ -256,15 +256,22 @@ static void init(void);
 
 // Each of these lines generates a replacement function:
 //     (from_so, from_fn,  v's replacement)
+// For some lines, we will also define a replacement function
+// whose only purpose is to be a soname synonym place holder
+// that can be replaced using --soname-synonyms.
+#define SO_SYN_MALLOC VG_SO_SYN(somalloc)
 
 // malloc
 #if defined(VGO_linux)
  ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc,      malloc);
  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      malloc,      malloc);
+ ALLOC_or_NULL(SO_SYN_MALLOC,         malloc,      malloc);
 
 #elif defined(VGO_darwin)
  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      malloc,      malloc);
- ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_zone_malloc, malloc);
+ ALLOC_or_NULL(SO_SYN_MALLOC,         malloc,      malloc);
+ ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME,  malloc_zone_malloc, malloc);
+ ZONEALLOC_or_NULL(SO_SYN_MALLOC,     malloc_zone_malloc, malloc);
 
 #endif
 
@@ -281,11 +288,13 @@ static void init(void);
  #if VG_WORDSIZE == 4
   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj,          __builtin_new);
   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwj,          __builtin_new);
+  ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znwj,          __builtin_new);
  #endif
  // operator new(unsigned long), GNU mangling
  #if VG_WORDSIZE == 8
   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm,          __builtin_new);
   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwm,          __builtin_new);
+  ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znwm,          __builtin_new);
  #endif
 
 #elif defined(VGO_darwin)
@@ -310,11 +319,13 @@ static void init(void);
  #if VG_WORDSIZE == 4
   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t,  __builtin_new);
   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwjRKSt9nothrow_t,  __builtin_new);
+  ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnwjRKSt9nothrow_t,  __builtin_new);
  #endif
  // operator new(unsigned long, std::nothrow_t const&), GNU mangling
  #if VG_WORDSIZE == 8
   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t,  __builtin_new);
   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwmRKSt9nothrow_t,  __builtin_new);
+  ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnwmRKSt9nothrow_t,  __builtin_new);
  #endif
 
 #elif defined(VGO_darwin)
@@ -342,11 +353,13 @@ static void init(void);
  #if VG_WORDSIZE == 4
   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj,             __builtin_vec_new );
   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znaj,             __builtin_vec_new );
+  ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znaj,             __builtin_vec_new );
  #endif
  // operator new[](unsigned long), GNU mangling
  #if VG_WORDSIZE == 8
   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam,             __builtin_vec_new );
   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znam,             __builtin_vec_new );
+  ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znam,             __builtin_vec_new );
  #endif
 
 #elif defined(VGO_darwin)
@@ -371,11 +384,13 @@ static void init(void);
  #if VG_WORDSIZE == 4
   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnajRKSt9nothrow_t, __builtin_vec_new );
+  ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnajRKSt9nothrow_t, __builtin_vec_new );
  #endif
  // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
  #if VG_WORDSIZE == 8
   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnamRKSt9nothrow_t, __builtin_vec_new );
+  ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnamRKSt9nothrow_t, __builtin_vec_new );
  #endif
 
 #elif defined(VGO_darwin)
@@ -422,13 +437,17 @@ static void init(void);
       (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
    }
 
+
 #if defined(VGO_linux)
  FREE(VG_Z_LIBSTDCXX_SONAME,  free,                 free );
  FREE(VG_Z_LIBC_SONAME,       free,                 free );
+ FREE(SO_SYN_MALLOC,          free,                 free );
 
 #elif defined(VGO_darwin)
  FREE(VG_Z_LIBC_SONAME,       free,                 free );
+ FREE(SO_SYN_MALLOC,          free,                 free );
  ZONEFREE(VG_Z_LIBC_SONAME,   malloc_zone_free,     free );
+ ZONEFREE(SO_SYN_MALLOC,      malloc_zone_free,     free );
 
 #endif
 
@@ -439,6 +458,7 @@ static void init(void);
 #if defined(VGO_linux)
  FREE(VG_Z_LIBSTDCXX_SONAME,  cfree,                free );
  FREE(VG_Z_LIBC_SONAME,       cfree,                free );
+ FREE(SO_SYN_MALLOC,          cfree,                free );
 
 #elif defined(VGO_darwin)
  //FREE(VG_Z_LIBSTDCXX_SONAME,  cfree,                free );
@@ -456,6 +476,7 @@ static void init(void);
  // operator delete(void*), GNU mangling
  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdlPv,               __builtin_delete );
  FREE(VG_Z_LIBC_SONAME,       _ZdlPv,               __builtin_delete );
+ FREE(SO_SYN_MALLOC,          _ZdlPv,               __builtin_delete );
 
 #elif defined(VGO_darwin)
  // operator delete(void*), GNU mangling
@@ -471,6 +492,7 @@ static void init(void);
  // operator delete(void*, std::nothrow_t const&), GNU mangling
  FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t,  __builtin_delete );
  FREE(VG_Z_LIBC_SONAME,      _ZdlPvRKSt9nothrow_t,  __builtin_delete );
+ FREE(SO_SYN_MALLOC,         _ZdlPvRKSt9nothrow_t,  __builtin_delete );
 
 #elif defined(VGO_darwin)
  // operator delete(void*, std::nothrow_t const&), GNU mangling
@@ -489,6 +511,7 @@ static void init(void);
  // operator delete[](void*), GNU mangling
  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
  FREE(VG_Z_LIBC_SONAME,       _ZdaPv,               __builtin_vec_delete );
+ FREE(SO_SYN_MALLOC,          _ZdaPv,               __builtin_vec_delete );
 
 #elif defined(VGO_darwin)
  // operator delete[](void*), not mangled (for gcc 2.96)
@@ -507,6 +530,7 @@ static void init(void);
  // operator delete[](void*, std::nothrow_t const&), GNU mangling
  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
  FREE(VG_Z_LIBC_SONAME,       _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
+ FREE(SO_SYN_MALLOC,          _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
 
 #elif defined(VGO_darwin)
  // operator delete[](void*, std::nothrow_t const&), GNU mangling
@@ -564,10 +588,13 @@ static void init(void);
 
 #if defined(VGO_linux)
  CALLOC(VG_Z_LIBC_SONAME, calloc);
+ CALLOC(SO_SYN_MALLOC,    calloc);
 
 #elif defined(VGO_darwin)
  CALLOC(VG_Z_LIBC_SONAME, calloc);
+ CALLOC(SO_SYN_MALLOC,    calloc);
  ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc);
+ ZONECALLOC(SO_SYN_MALLOC,    malloc_zone_calloc);
 
 #endif
 
@@ -630,10 +657,13 @@ static void init(void);
 
 #if defined(VGO_linux)
  REALLOC(VG_Z_LIBC_SONAME, realloc);
+ REALLOC(SO_SYN_MALLOC,    realloc);
 
 #elif defined(VGO_darwin)
  REALLOC(VG_Z_LIBC_SONAME, realloc);
+ REALLOC(SO_SYN_MALLOC,    realloc);
  ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc);
+ ZONEREALLOC(SO_SYN_MALLOC,    malloc_zone_realloc);
 
 #endif
 
@@ -692,10 +722,13 @@ static void init(void);
 
 #if defined(VGO_linux)
  MEMALIGN(VG_Z_LIBC_SONAME, memalign);
+ MEMALIGN(SO_SYN_MALLOC,    memalign);
 
 #elif defined(VGO_darwin)
  MEMALIGN(VG_Z_LIBC_SONAME, memalign);
+ MEMALIGN(SO_SYN_MALLOC,    memalign);
  ZONEMEMALIGN(VG_Z_LIBC_SONAME, malloc_zone_memalign);
+ ZONEMEMALIGN(SO_SYN_MALLOC,    malloc_zone_memalign);
 
 #endif
 
@@ -730,10 +763,13 @@ static void init(void);
 
 #if defined(VGO_linux)
  VALLOC(VG_Z_LIBC_SONAME, valloc);
+ VALLOC(SO_SYN_MALLOC, valloc);
 
 #elif defined(VGO_darwin)
  VALLOC(VG_Z_LIBC_SONAME, valloc);
+ VALLOC(SO_SYN_MALLOC, valloc);
  ZONEVALLOC(VG_Z_LIBC_SONAME, malloc_zone_valloc);
+ ZONEVALLOC(SO_SYN_MALLOC,    malloc_zone_valloc);
 
 #endif
 
@@ -754,6 +790,7 @@ static void init(void);
 
 #if defined(VGO_linux)
  MALLOPT(VG_Z_LIBC_SONAME, mallopt);
+ MALLOPT(SO_SYN_MALLOC,    mallopt);
 
 #elif defined(VGO_darwin)
  //MALLOPT(VG_Z_LIBC_SONAME, mallopt);
@@ -796,6 +833,7 @@ static void init(void);
 
 #if defined(VGO_linux)
  MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
+ MALLOC_TRIM(SO_SYN_MALLOC,    malloc_trim);
 
 #elif defined(VGO_darwin)
  //MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
@@ -833,6 +871,7 @@ static void init(void);
 
 #if defined(VGO_linux)
  POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
+ POSIX_MEMALIGN(SO_SYN_MALLOC,    posix_memalign);
 
 #elif defined(VGO_darwin)
  //POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
@@ -862,14 +901,18 @@ static void init(void);
 
 #if defined(VGO_linux)
  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
+ MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_usable_size);
  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
+ MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_size);
 # if defined(VGPV_arm_linux_android)
   MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, dlmalloc_usable_size);
+  MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    dlmalloc_usable_size);
 # endif
 
 #elif defined(VGO_darwin)
  //MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
+ MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_size);
 
 #endif
 
@@ -916,6 +959,7 @@ static void panic(const char *str)
 
 #if defined(VGO_linux)
  MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
+ MALLOC_STATS(SO_SYN_MALLOC,    malloc_stats);
 
 #elif defined(VGO_darwin)
  //MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
@@ -942,6 +986,7 @@ static void panic(const char *str)
 
 #if defined(VGO_linux)
  MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
+ MALLINFO(SO_SYN_MALLOC,    mallinfo);
 
 #elif defined(VGO_darwin)
  //MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
@@ -996,6 +1041,7 @@ static vki_malloc_zone_t vg_default_zone = {
    }
 
 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone);
+DEFAULT_ZONE(SO_SYN_MALLOC,    malloc_default_zone);
 
 
 #define ZONE_FROM_PTR(soname, fnname) \
@@ -1007,6 +1053,7 @@ DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone);
    }
 
 ZONE_FROM_PTR(VG_Z_LIBC_SONAME, malloc_zone_from_ptr);
+ZONE_FROM_PTR(SO_SYN_MALLOC,    malloc_zone_from_ptr);
 
 
 // GrP fixme bypass libc's use of zone->introspect->check
index 55599848816670936cb9af162bd85680ef260cee..5e81b768d7848ddbb21e2387c87526fff7c69d36 100644 (file)
@@ -86,6 +86,10 @@ extern Int   VG_(clo_sanity_level);
 /* Automatically attempt to demangle C++ names?  default: YES */
 extern Bool  VG_(clo_demangle);
 /* Simulate child processes? default: NO */
+/* Soname synonyms : a string containing a list of pairs
+   xxxxx=yyyyy separated by commas.
+   E.g. --soname-synonyms=somalloc=libtcmalloc*.so*,solibtruc=NONE */
+extern HChar* VG_(clo_soname_synonyms);
 extern Bool  VG_(clo_trace_children);
 /* String containing comma-separated patterns for executable names
    that should not be traced into even when --trace-children=yes */
index 62a5ae9b23b03667ac86ccbdd7ffb49bed0187fc..70c8b8ac26bbf1a3498b46455fcb0ecc53a5c8cd 100644 (file)
@@ -1787,6 +1787,62 @@ need to use these.</para>
    </listitem>
   </varlistentry>
 
+  <varlistentry id="opt.soname-synonyms"
+        xreflabel="--soname-synonyms">
+    <term>
+      <option><![CDATA[--soname-synonyms=syn1=pattern1,syn2=pattern2,...]]></option>
+    </term>
+    <listitem>
+      <para>When a shared library is loaded, Valgrind examines if some
+      functions of this library must be replaced or wrapped.
+      For example, memcheck is replacing the malloc related
+      functions (malloc, free, calloc, ...).
+      Such replacements are done by default only in shared libraries whose
+      soname matches a predefined soname pattern (e.g.
+      <varname>libc.so*</varname> on linux).
+      By default, no replacement is done for a statically linked
+      library or for alternative libraries such as tcmalloc.
+      In some cases, the replacements allow
+      <option>--soname-synonyms</option> to specify one additional
+      synonym pattern, giving flexibility in the replacement. </para>
+
+      <para> Currently, this flexibility is only allowed for the
+      malloc related functions, using the
+      synonym <varname>somalloc</varname>.  This synonym is usable for
+      all tools doing standard replacement of malloc related functions
+      (e.g. memcheck, massif, drd, helgrind, exp-dhat, exp-sgcheck).
+      </para>
+
+      <itemizedlist>
+        <listitem>
+
+          <para>Alternate malloc library: to replace the malloc
+          related functions in an alternate library with
+          soname <varname>mymalloclib.so</varname>, give the
+          option <option>--soname-synonyms=somalloc=mymalloclib.so</option>.
+          A pattern can be used to match multiple libraries sonames.
+          For
+          example, <option>--soname-synonyms=somalloc=*tcmalloc*</option>
+          will match the soname of all variants of the tcmalloc library
+          (native, debug, profiled, ... tcmalloc variants). </para>
+          <para>Note: the soname of a elf shared library can be
+          retrieved using the readelf utility. </para>
+
+        </listitem>
+
+        <listitem>
+          <para>Replacements in a statically linked library are done by
+          using the <varname>NONE</varname> pattern. For example, if
+          you link with <varname>libtcmalloc.a</varname>, memcheck 
+          will properly work when you give the
+          option <option>--soname-synonyms=somalloc=NONE</option>.  Note
+          that a NONE pattern will match the main executable and any
+          shared library having no soname. </para>
+        </listitem>
+      </itemizedlist>
+   </listitem>
+  </varlistentry>
+
 
 </variablelist>
 <!-- end of xi:include in the manpage -->
index 738f4338648473da24f293918acc8fce8a20b146..9311fd099963362a47504e2d92c61b6adf2d06aa 100644 (file)
 #endif
 
 
+// Prefix for synonym soname synonym handling
+#define VG_SO_SYN(name)       VgSoSyn##name
+#define VG_SO_SYN_PREFIX     "VgSoSyn"
+#define VG_SO_SYN_PREFIX_LEN 7
+
 #endif   // __PUB_TOOL_REDIR_H
 
 /*--------------------------------------------------------------------*/
index 06d25fcabc485438e0d4be2e3c444edc544a4bb8..d420857d235e4a27cfca339024ca92025b271451 100644 (file)
@@ -178,6 +178,7 @@ EXTRA_DIST = \
        sigkill.stderr.exp sigkill.stderr.exp-darwin sigkill.vgtest \
        signal2.stderr.exp signal2.stdout.exp signal2.vgtest \
        sigprocmask.stderr.exp sigprocmask.stderr.exp2 sigprocmask.vgtest \
+       static_malloc.stderr.exp static_malloc.vgtest \
        strchr.stderr.exp strchr.stderr.exp2 strchr.stderr.exp-darwin \
            strchr.vgtest \
        str_tester.stderr.exp str_tester.vgtest \
@@ -268,7 +269,7 @@ check_PROGRAMS = \
        realloc1 realloc2 realloc3 \
        sbfragment \
        sh-mem sh-mem-random \
-       sigaltstack signal2 sigprocmask sigkill \
+       sigaltstack signal2 sigprocmask static_malloc sigkill \
        strchr \
        str_tester \
        supp_unknown supp1 supp2 suppfree \
diff --git a/memcheck/tests/static_malloc.c b/memcheck/tests/static_malloc.c
new file mode 100644 (file)
index 0000000..22def9e
--- /dev/null
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+static char buf[10000];
+static int bufi = 0;
+void* malloc(size_t i) {
+   bufi += i;
+   return buf + bufi - i;
+}
+
+void free(void*ptr) {
+}
+
+int main (void)
+{
+   char *p;
+   p = malloc(10);
+   p = malloc(123);
+   free(p);
+   return 0;
+}
+
diff --git a/memcheck/tests/static_malloc.stderr.exp b/memcheck/tests/static_malloc.stderr.exp
new file mode 100644 (file)
index 0000000..5090107
--- /dev/null
@@ -0,0 +1,4 @@
+10 bytes in 1 blocks are definitely lost in loss record ... of ...
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: main (static_malloc.c:16)
+
diff --git a/memcheck/tests/static_malloc.vgtest b/memcheck/tests/static_malloc.vgtest
new file mode 100644 (file)
index 0000000..7d3a455
--- /dev/null
@@ -0,0 +1,2 @@
+prog: static_malloc
+vgopts: -q --leak-check=full --soname-synonyms=somalloc=NONE
index 369e999e58e1d513fe6fa1d764be6fe38116b4fc..12dafde30a441ea4a9d8b0c8039a5c6c4c65074e 100644 (file)
@@ -80,6 +80,9 @@ usage: valgrind [options] prog-and-args
     --require-text-symbol=:sonamepattern:symbolpattern    abort run if the
                               stated shared object doesn't have the stated
                               text symbol.  Patterns can contain ? and *.
+    --soname-synonyms=syn1=pattern1,syn2=pattern2,... synonym soname
+                              patterns for some Valgrind wrapping
+                              or replacement (such as malloc replacement)
 
   user options for Nulgrind:
     (none)
index 5cf446c1952f746060e835e2a5a3cde43f7e3af5..25de98592f397e50f3c772aceabe02088b06848c 100644 (file)
@@ -80,6 +80,9 @@ usage: valgrind [options] prog-and-args
     --require-text-symbol=:sonamepattern:symbolpattern    abort run if the
                               stated shared object doesn't have the stated
                               text symbol.  Patterns can contain ? and *.
+    --soname-synonyms=syn1=pattern1,syn2=pattern2,... synonym soname
+                              patterns for some Valgrind wrapping
+                              or replacement (such as malloc replacement)
 
   user options for Nulgrind:
     (none)