|
From: <sv...@va...> - 2013-10-17 22:10:57
|
Author: philippe
Date: Thu Oct 17 22:10:41 2013
New Revision: 13651
Log:
Allow tools to provide some statistics in suppression list produced at the end
Option -v outputs a list of used suppressions. This only gives
the nr of times a suppression was used.
For a leak search, this only gives the nr of loss records that
have been suppressed, but it does not give additional needed details
to understand more precisely what has been suppressed
(i.e. nr of blocks and nr of bytes).
=> Add in the tool interface update_extra_suppression_use and
print_extra_suppression_info functions to allow the tool to record
additioonal use statistics for a suppression. These statistics
can be done depending on the error (and its data) which is suppressed.
Use this in memcheck for the leak suppressions, to maintain and output
the nr of blocks and bytes suppressed by a suppression during
the last leak search.
Modified:
trunk/NEWS
trunk/coregrind/m_errormgr.c
trunk/coregrind/m_tooliface.c
trunk/coregrind/pub_core_tooliface.h
trunk/docs/xml/manual-core.xml
trunk/drd/drd_error.c
trunk/exp-sgcheck/pc_common.c
trunk/exp-sgcheck/pc_common.h
trunk/exp-sgcheck/pc_main.c
trunk/helgrind/hg_errors.c
trunk/helgrind/hg_errors.h
trunk/helgrind/hg_main.c
trunk/include/pub_tool_tooliface.h
trunk/memcheck/docs/mc-manual.xml
trunk/memcheck/mc_errors.c
trunk/memcheck/mc_include.h
trunk/memcheck/mc_leakcheck.c
trunk/memcheck/mc_main.c
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Thu Oct 17 22:10:41 2013
@@ -32,6 +32,12 @@
for 'use after free' errors or to decrease Valgrind memory and/or cpu usage
by recording less information for heap blocks.
+ - The list of used suppressions (shown when giving the -v option)
+ now shows for the leak suppressions how many blocks and bytes were
+ suppressed during the last leak search for each suppression.
+ The suppression count for a leak suppression shows the total nr
+ of loss records which were suppressed by this suppression.
+
* ==================== OTHER CHANGES ====================
- Option --merge-recursive-frames=<number> tells Valgrind to
@@ -63,6 +69,9 @@
'v.do expensive_sanity_check_general' that checks the sanity
of various Valgrind aspects, including the Valgrind heap.
+ - The list of used suppressions (shown when giving the -v option)
+ now gives the filename and linenr where the suppression is defined.
+
- remote debuginfo server + overhaul of debuginfo reading
- some fixes for OSX 10.8
Modified: trunk/coregrind/m_errormgr.c
==============================================================================
--- trunk/coregrind/m_errormgr.c (original)
+++ trunk/coregrind/m_errormgr.c Thu Oct 17 22:10:41 2013
@@ -913,12 +913,19 @@
" </pair>\n",
su->count, su->sname );
} else {
+ HChar xtra[256]; /* assumed big enough (is overrun-safe) */
+ Bool anyXtra;
// blank line before the first shown suppression, if any
if (!any_supp)
VG_(dmsg)("\n");
- VG_(dmsg)("used_suppression: %6d %s %s:%d\n", su->count, su->sname,
+ VG_(memset)(xtra, 0, sizeof(xtra));
+ anyXtra = VG_TDICT_CALL(tool_print_extra_suppression_use,
+ su, xtra, sizeof(xtra));
+ vg_assert(xtra[sizeof(xtra)-1] == 0);
+ VG_(dmsg)("used_suppression: %6d %s %s:%d%s%s\n", su->count, su->sname,
VG_(clo_suppressions)[su->clo_suppressions_i],
- su->sname_lineno);
+ su->sname_lineno,
+ anyXtra ? " " : "", xtra);
}
any_supp = True;
}
@@ -1659,8 +1666,9 @@
/* Conceptually, ip2fo contains an array of function names and an array of
object names, corresponding to the array of IP of err->where.
These names are just computed 'on demand' (so once maximum),
- then stored (efficiently, avoiding too many allocs) in ip2fo to be re-usable
- for the matching of the same IP with the next suppression pattern.
+ then stored (efficiently, avoiding too many allocs) in ip2fo to be
+ re-usable for the matching of the same IP with the next suppression
+ pattern.
VG_(generic_match) gets this 'IP to Fun or Obj name completer' as one
of its arguments. It will then pass it to the function
@@ -1687,7 +1695,10 @@
em_supplist_cmps++;
if (supp_matches_error(su, err)
&& supp_matches_callers(&ip2fo, su)) {
- /* got a match. Move this entry to the head of the list
+ /* got a match. */
+ /* Inform the tool that err is suppressed by su. */
+ (void)VG_TDICT_CALL(tool_update_extra_suppression_use, err, su);
+ /* Move this entry to the head of the list
in the hope of making future searches cheaper. */
if (su_prev) {
vg_assert(su_prev->next == su);
Modified: trunk/coregrind/m_tooliface.c
==============================================================================
--- trunk/coregrind/m_tooliface.c (original)
+++ trunk/coregrind/m_tooliface.c Thu Oct 17 22:10:41 2013
@@ -234,7 +234,9 @@
Bool (*read_extra) (Int, HChar**, SizeT*, Int*, Supp*),
Bool (*matches) (Error*, Supp*),
const HChar* (*name) (Error*),
- Bool (*get_xtra_si)(Error*,/*OUT*/HChar*,Int)
+ Bool (*get_xtra_si)(Error*,/*OUT*/HChar*,Int),
+ Bool (*print_xtra_su)(Supp*,/*OUT*/HChar*,Int),
+ void (*update_xtra_su)(Error*, Supp*)
)
{
VG_(needs).tool_errors = True;
@@ -248,6 +250,8 @@
VG_(tdict).tool_error_matches_suppression = matches;
VG_(tdict).tool_get_error_name = name;
VG_(tdict).tool_get_extra_suppression_info = get_xtra_si;
+ VG_(tdict).tool_print_extra_suppression_use = print_xtra_su;
+ VG_(tdict).tool_update_extra_suppression_use = update_xtra_su;
}
void VG_(needs_command_line_options)(
Modified: trunk/coregrind/pub_core_tooliface.h
==============================================================================
--- trunk/coregrind/pub_core_tooliface.h (original)
+++ trunk/coregrind/pub_core_tooliface.h Thu Oct 17 22:10:41 2013
@@ -127,6 +127,8 @@
Bool (*tool_error_matches_suppression) (Error*, Supp*);
const HChar* (*tool_get_error_name) (Error*);
Bool (*tool_get_extra_suppression_info) (Error*,/*OUT*/HChar*,Int);
+ Bool (*tool_print_extra_suppression_use) (Supp*,/*OUT*/HChar*,Int);
+ void (*tool_update_extra_suppression_use) (Error*, Supp*);
// VG_(needs).superblock_discards
void (*tool_discard_superblock_info)(Addr64, VexGuestExtents);
Modified: trunk/docs/xml/manual-core.xml
==============================================================================
--- trunk/docs/xml/manual-core.xml (original)
+++ trunk/docs/xml/manual-core.xml Thu Oct 17 22:10:41 2013
@@ -384,14 +384,17 @@
specification of errors to suppress.</para>
<para>If you use the <option>-v</option> option, at the end of execution,
-Valgrind prints out one line for each used suppression, giving its name
-and the number of times it got used. Here's the suppressions used by a
-run of <computeroutput>valgrind --tool=memcheck ls -l</computeroutput>:</para>
+Valgrind prints out one line for each used suppression, giving the number of times
+it got used, its name and the filename and line number where the suppression is
+defined. Depending on the suppression kind, the filename and line number are optionally
+followed by additional information (such as the number of blocks and bytes suppressed
+by a memcheck leak suppression). Here's the suppressions used by a
+run of <computeroutput>valgrind -v --tool=memcheck ls -l</computeroutput>:</para>
<programlisting><![CDATA[
---27579-- supp: 1 socketcall.connect(serv_addr)/__libc_connect/__nscd_getgrgid_r
---27579-- supp: 1 socketcall.connect(serv_addr)/__libc_connect/__nscd_getpwuid_r
---27579-- supp: 6 strrchr/_dl_map_object_from_fd/_dl_map_object]]></programlisting>
+--1610-- used_suppression: 2 dl-hack3-cond-1 /usr/lib/valgrind/default.supp:1234
+--1610-- used_suppression: 2 glibc-2.5.x-on-SUSE-10.2-(PPC)-2a /usr/lib/valgrind/default.supp:1234
+]]></programlisting>
<para>Multiple suppressions files are allowed. By default, Valgrind
uses <filename>$PREFIX/lib/valgrind/default.supp</filename>. You can
Modified: trunk/drd/drd_error.c
==============================================================================
--- trunk/drd/drd_error.c (original)
+++ trunk/drd/drd_error.c Thu Oct 17 22:10:41 2013
@@ -608,6 +608,19 @@
return False;
}
+static
+Bool drd_print_extra_suppression_use(Supp* su,
+ /*OUT*/HChar* buf, Int nBuf)
+{
+ return False;
+}
+
+static
+void drd_update_extra_suppresion_use(Error* e, Supp* supp)
+{
+ return;
+}
+
/** Tell the Valgrind core about DRD's error handlers. */
void DRD_(register_error_handlers)(void)
{
@@ -620,5 +633,7 @@
drd_read_extra_suppression_info,
drd_error_matches_suppression,
drd_get_error_name,
- drd_get_extra_suppression_info);
+ drd_get_extra_suppression_info,
+ drd_print_extra_suppression_use,
+ drd_update_extra_suppresion_use);
}
Modified: trunk/exp-sgcheck/pc_common.c
==============================================================================
--- trunk/exp-sgcheck/pc_common.c (original)
+++ trunk/exp-sgcheck/pc_common.c Thu Oct 17 22:10:41 2013
@@ -793,6 +793,16 @@
}
}
+Bool pc_print_extra_suppression_use ( Supp* su,
+ /*OUT*/HChar* buf, Int nBuf )
+{
+ return False;
+}
+
+void pc_update_extra_suppression_use (Error* err, Supp* su)
+{
+ return;
+}
/*--------------------------------------------------------------------*/
/*--- end pc_common.c ---*/
Modified: trunk/exp-sgcheck/pc_common.h
==============================================================================
--- trunk/exp-sgcheck/pc_common.h (original)
+++ trunk/exp-sgcheck/pc_common.h Thu Oct 17 22:10:41 2013
@@ -58,6 +58,9 @@
const HChar* pc_get_error_name ( Error* err );
Bool pc_get_extra_suppression_info ( Error* err,
/*OUT*/HChar* buf, Int nBuf );
+Bool pc_print_extra_suppression_use ( Supp* su,
+ /*OUT*/HChar* buf, Int nBuf );
+void pc_update_extra_suppression_use (Error* err, Supp* su);
extern Bool h_clo_partial_loads_ok;
/* extern Bool h_clo_lossage_check; */
Modified: trunk/exp-sgcheck/pc_main.c
==============================================================================
--- trunk/exp-sgcheck/pc_main.c (original)
+++ trunk/exp-sgcheck/pc_main.c Thu Oct 17 22:10:41 2013
@@ -105,7 +105,9 @@
pc_read_extra_suppression_info,
pc_error_matches_suppression,
pc_get_error_name,
- pc_get_extra_suppression_info);
+ pc_get_extra_suppression_info,
+ pc_print_extra_suppression_use,
+ pc_update_extra_suppression_use);
VG_(needs_xml_output) ();
Modified: trunk/helgrind/hg_errors.c
==============================================================================
--- trunk/helgrind/hg_errors.c (original)
+++ trunk/helgrind/hg_errors.c Thu Oct 17 22:10:41 2013
@@ -1396,6 +1396,19 @@
return False;
}
+Bool HG_(print_extra_suppression_use) ( Supp* su,
+ /*OUT*/HChar* buf, Int nBuf )
+{
+ /* Do nothing */
+ return False;
+}
+
+void HG_(update_extra_suppression_use) ( Error* err, Supp* su )
+{
+ /* Do nothing */
+ return;
+}
+
/*--------------------------------------------------------------------*/
/*--- end hg_errors.c ---*/
Modified: trunk/helgrind/hg_errors.h
==============================================================================
--- trunk/helgrind/hg_errors.h (original)
+++ trunk/helgrind/hg_errors.h Thu Oct 17 22:10:41 2013
@@ -46,6 +46,9 @@
const HChar* HG_(get_error_name) ( Error* err );
Bool HG_(get_extra_suppression_info) ( Error* err,
/*OUT*/HChar* buf, Int nBuf );
+Bool HG_(print_extra_suppression_use) ( Supp* su,
+ /*OUT*/HChar* buf, Int nBuf );
+void HG_(update_extra_suppression_use) ( Error* err, Supp* su );
/* Functions for recording various kinds of errors. */
void HG_(record_error_Race) ( Thread* thr,
Modified: trunk/helgrind/hg_main.c
==============================================================================
--- trunk/helgrind/hg_main.c (original)
+++ trunk/helgrind/hg_main.c Thu Oct 17 22:10:41 2013
@@ -5286,7 +5286,9 @@
HG_(read_extra_suppression_info),
HG_(error_matches_suppression),
HG_(get_error_name),
- HG_(get_extra_suppression_info));
+ HG_(get_extra_suppression_info),
+ HG_(print_extra_suppression_use),
+ HG_(update_extra_suppression_use));
VG_(needs_xml_output) ();
Modified: trunk/include/pub_tool_tooliface.h
==============================================================================
--- trunk/include/pub_tool_tooliface.h (original)
+++ trunk/include/pub_tool_tooliface.h Thu Oct 17 22:10:41 2013
@@ -343,7 +343,20 @@
// do nothing, and return False. This function is the inverse of
// VG_(tdict).tool_read_extra_suppression_info().
Bool (*print_extra_suppression_info)(Error* err,
- /*OUT*/HChar* buf, Int nBuf)
+ /*OUT*/HChar* buf, Int nBuf),
+
+ // This is similar to print_extra_suppression_info, but is used
+ // to print information such as additional statistical counters
+ // as part of the used suppression list produced by -v.
+ Bool (*print_extra_suppression_use)(Supp* su,
+ /*OUT*/HChar* buf, Int nBuf),
+
+ // Called by error mgr once it has been established that err
+ // is suppressed by su. update_extra_suppression_use typically
+ // can be used to update suppression extra information such as
+ // some statistical counters that will be printed by
+ // print_extra_suppression_use.
+ void (*update_extra_suppression_use)(Error* err, Supp* su)
);
/* Is information kept by the tool about specific instructions or
Modified: trunk/memcheck/docs/mc-manual.xml
==============================================================================
--- trunk/memcheck/docs/mc-manual.xml (original)
+++ trunk/memcheck/docs/mc-manual.xml Thu Oct 17 22:10:41 2013
@@ -1166,11 +1166,28 @@
<computeroutput><set></computeroutput> is specified similarly
to the option <option>--show-leak-kinds</option>.
If this optional extra line is not present, the suppression entry will match
-all leak kinds.
-</para>
+all leak kinds. </para>
<para>The other memcheck error kinds do not have extra lines.</para>
+<para>
+If you give the <option>-v</option> option, Valgrind will print
+the list of used suppressions at the end of the execution.
+For a leak suppression, this output gives the number of different
+loss records that matches the suppression, the number of bytes
+and blocks suppressed by the suppressions.
+In case several leak searches are done, the number of bytes and blocks
+are reset to 0 before a new leak search. Note that the number of different
+loss records is not reset to 0.
+<para>In the example below, in the last leak search, 7 blocks and 96 bytes have
+been suppressed by the <option>some_leak_suppression</option>
+suppression. </para>
+<programlisting><![CDATA[
+--21041-- used_suppression: 10 some_other_leak_suppression s.supp:14 suppressed: 12,400 bytes in 1 blocks
+--21041-- used_suppression: 39 some_leak_suppression s.supp:2 suppressed: 96 bytes in 7 blocks
+]]></programlisting>
+</para>
+
<para>The first line of the calling context: for <varname>ValueN</varname>
and <varname>AddrN</varname> errors, it is either the name of the function
in which the error occurred, or, failing that, the full path of the
Modified: trunk/memcheck/mc_errors.c
==============================================================================
--- trunk/memcheck/mc_errors.c (original)
+++ trunk/memcheck/mc_errors.c Thu Oct 17 22:10:41 2013
@@ -1532,6 +1532,14 @@
struct _MC_LeakSuppExtra {
UInt match_leak_kinds;
+
+ /* Maintains nr of blocks and bytes suppressed with this suppression
+ during the leak search identified by leak_search_gen.
+ blocks_suppressed and bytes_suppressed are reset to 0 when
+ used the first time during a leak search. */
+ SizeT blocks_suppressed;
+ SizeT bytes_suppressed;
+ UInt leak_search_gen;
};
Bool MC_(read_extra_suppression_info) ( Int fd, HChar** bufpp,
@@ -1549,6 +1557,9 @@
MC_LeakSuppExtra* lse;
lse = VG_(malloc)("mc.resi.2", sizeof(MC_LeakSuppExtra));
lse->match_leak_kinds = RallS;
+ lse->blocks_suppressed = 0;
+ lse->bytes_suppressed = 0;
+ lse->leak_search_gen = 0;
VG_(set_supp_extra)(su, lse); // By default, all kinds will match.
eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
if (eof) return True; // old LeakSupp style, no match-leak-kinds line.
@@ -1617,6 +1628,13 @@
case LeakSupp:
if (ekind == Err_Leak) {
MC_LeakSuppExtra* lse = (MC_LeakSuppExtra*) VG_(get_supp_extra)(su);
+ if (lse->leak_search_gen != MC_(leak_search_gen)) {
+ // First time we see this suppression during this leak search.
+ // => reset the counters to 0.
+ lse->blocks_suppressed = 0;
+ lse->bytes_suppressed = 0;
+ lse->leak_search_gen = MC_(leak_search_gen);
+ }
return RiS(extra->Err.Leak.lr->key.state, lse->match_leak_kinds);
} else
return False;
@@ -1695,6 +1713,37 @@
}
}
+Bool MC_(print_extra_suppression_use) ( Supp *su,
+ /*OUT*/HChar *buf, Int nBuf )
+{
+ if (VG_(get_supp_kind)(su) == LeakSupp) {
+ MC_LeakSuppExtra *lse = (MC_LeakSuppExtra*) VG_(get_supp_extra) (su);
+
+ if (lse->leak_search_gen == MC_(leak_search_gen)
+ && lse->blocks_suppressed > 0) {
+ VG_(snprintf) (buf, nBuf-1,
+ "suppressed: %'lu bytes in %'lu blocks",
+ lse->bytes_suppressed,
+ lse->blocks_suppressed);
+ return True;
+ } else
+ return False;
+ } else
+ return False;
+}
+
+void MC_(update_extra_suppression_use) ( Error* err, Supp* su)
+{
+ if (VG_(get_supp_kind)(su) == LeakSupp) {
+ MC_LeakSuppExtra *lse = (MC_LeakSuppExtra*) VG_(get_supp_extra) (su);
+ MC_Error* extra = VG_(get_error_extra)(err);
+
+ tl_assert (lse->leak_search_gen = MC_(leak_search_gen));
+ lse->blocks_suppressed += extra->Err.Leak.lr->num_blocks;
+ lse->bytes_suppressed
+ += extra->Err.Leak.lr->szB + extra->Err.Leak.lr->indirect_szB;
+ }
+}
/*--------------------------------------------------------------------*/
/*--- end mc_errors.c ---*/
Modified: trunk/memcheck/mc_include.h
==============================================================================
--- trunk/memcheck/mc_include.h (original)
+++ trunk/memcheck/mc_include.h Thu Oct 17 22:10:41 2013
@@ -351,6 +351,10 @@
void MC_(detect_memory_leaks) ( ThreadId tid, LeakCheckParams * lcp);
+// Each time a leak search is done, the leak search generation
+// MC_(leak_search_gen) is incremented.
+extern UInt MC_(leak_search_gen);
+
// maintains the lcp.deltamode given in the last call to detect_memory_leaks
extern LeakCheckDeltaMode MC_(detect_memory_leaks_last_delta_mode);
@@ -404,6 +408,9 @@
Bool MC_(get_extra_suppression_info) ( Error* err,
/*OUT*/HChar* buf, Int nBuf );
+Bool MC_(print_extra_suppression_use) ( Supp* su,
+ /*OUT*/HChar* buf, Int nBuf );
+void MC_(update_extra_suppression_use) ( Error* err, Supp* su );
const HChar* MC_(get_error_name) ( Error* err );
Modified: trunk/memcheck/mc_leakcheck.c
==============================================================================
--- trunk/memcheck/mc_leakcheck.c (original)
+++ trunk/memcheck/mc_leakcheck.c Thu Oct 17 22:10:41 2013
@@ -474,6 +474,10 @@
// The below avoids replicating the delta_mode in each LossRecord.
LeakCheckDeltaMode MC_(detect_memory_leaks_last_delta_mode);
+// Each leak search run increments the below generation counter.
+// A used suppression during a leak search will contain this
+// generation number.
+UInt MC_(leak_search_gen);
// Records chunks that are currently being processed. Each element in the
// stack is an index into lc_chunks and lc_extras. Its size is
@@ -1646,7 +1650,7 @@
// before checking for (smaller) page skipping.
tl_assert((SM_SIZE % VKI_PAGE_SIZE) == 0);
-
+ MC_(leak_search_gen)++;
MC_(detect_memory_leaks_last_delta_mode) = lcp->deltamode;
detect_memory_leaks_last_heuristics = lcp->heuristics;
Modified: trunk/memcheck/mc_main.c
==============================================================================
--- trunk/memcheck/mc_main.c (original)
+++ trunk/memcheck/mc_main.c Thu Oct 17 22:10:41 2013
@@ -6699,7 +6699,9 @@
MC_(read_extra_suppression_info),
MC_(error_matches_suppression),
MC_(get_error_name),
- MC_(get_extra_suppression_info));
+ MC_(get_extra_suppression_info),
+ MC_(print_extra_suppression_use),
+ MC_(update_extra_suppression_use));
VG_(needs_libc_freeres) ();
VG_(needs_command_line_options)(mc_process_cmd_line_options,
mc_print_usage,
|