fix 219156 support static malloc or alternate malloc lib (e.g. tcmalloc) with new option --soname-synonyms
* 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
diff --git a/NEWS b/NEWS
index d874874..fef2b28 100644
--- a/NEWS
+++ b/NEWS
@@ -3,17 +3,22 @@
* ================== 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 @@
- 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 @@
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
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 89b7571..71065ce 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -187,6 +187,9 @@
" --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 @@
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)) {}
diff --git a/coregrind/m_options.c b/coregrind/m_options.c
index df00193..ca186c0 100644
--- a/coregrind/m_options.c
+++ b/coregrind/m_options.c
@@ -66,6 +66,7 @@
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;
diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c
index c7936b1..fd24c1a 100644
--- a/coregrind/m_redir.c
+++ b/coregrind/m_redir.c
@@ -367,6 +367,18 @@
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 @@
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);
diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c
index a0d3d87..bec413a 100644
--- a/coregrind/m_replacemalloc/vg_replace_malloc.c
+++ b/coregrind/m_replacemalloc/vg_replace_malloc.c
@@ -256,15 +256,22 @@
// 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 @@
#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 @@
#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 @@
#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 @@
#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 @@
(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 @@
#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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
#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 @@
#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 @@
#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 @@
#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 @@
#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 @@
#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 @@
#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 @@
#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 @@
#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 @@
#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 @@
}
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 @@
}
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
diff --git a/coregrind/pub_core_options.h b/coregrind/pub_core_options.h
index 5559984..5e81b76 100644
--- a/coregrind/pub_core_options.h
+++ b/coregrind/pub_core_options.h
@@ -86,6 +86,10 @@
/* 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 */
diff --git a/docs/xml/manual-core.xml b/docs/xml/manual-core.xml
index 62a5ae9..70c8b8a 100644
--- a/docs/xml/manual-core.xml
+++ b/docs/xml/manual-core.xml
@@ -1787,6 +1787,62 @@
</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 -->
diff --git a/include/pub_tool_redir.h b/include/pub_tool_redir.h
index 738f433..9311fd0 100644
--- a/include/pub_tool_redir.h
+++ b/include/pub_tool_redir.h
@@ -300,6 +300,11 @@
#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
/*--------------------------------------------------------------------*/
diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am
index 06d25fc..d420857 100644
--- a/memcheck/tests/Makefile.am
+++ b/memcheck/tests/Makefile.am
@@ -178,6 +178,7 @@
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 @@
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
index 0000000..22def9e
--- /dev/null
+++ b/memcheck/tests/static_malloc.c
@@ -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
index 0000000..5090107
--- /dev/null
+++ b/memcheck/tests/static_malloc.stderr.exp
@@ -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
index 0000000..7d3a455
--- /dev/null
+++ b/memcheck/tests/static_malloc.vgtest
@@ -0,0 +1,2 @@
+prog: static_malloc
+vgopts: -q --leak-check=full --soname-synonyms=somalloc=NONE
diff --git a/none/tests/cmdline1.stdout.exp b/none/tests/cmdline1.stdout.exp
index 369e999..12dafde 100644
--- a/none/tests/cmdline1.stdout.exp
+++ b/none/tests/cmdline1.stdout.exp
@@ -80,6 +80,9 @@
--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)
diff --git a/none/tests/cmdline2.stdout.exp b/none/tests/cmdline2.stdout.exp
index 5cf446c..25de985 100644
--- a/none/tests/cmdline2.stdout.exp
+++ b/none/tests/cmdline2.stdout.exp
@@ -80,6 +80,9 @@
--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)