Valgrind: r16205 - in /trunk: ./ coregrind/ docs/xml/ gdbserver_tests/ memcheck/ memcheck/docs/

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Valgrind: r16205 - in /trunk: ./ coregrind/ docs/xml/ gdbserver_tests/ memcheck/ memcheck/docs/

svn-2
Author: philippe
Date: Sat Jan 21 11:00:39 2017
New Revision: 16205

Log:
Allow memcheck to output the leak results as a callgrind xtree file.

* New command line options --xtree-leak=no|yes and --xtree-leak-file=<file>
  to produce the end of execution leak report in a xtree callgrind format
  file.

* New option 'xtleak' in the memcheck leak_check monitor command, to
  produce the leak report in an xtree file.

* File name template arguments (such as --log-file, --xtree-memory-file, ...)
  have a new %n format letter that is replaced by a sequence number.


Modified:
    trunk/NEWS
    trunk/coregrind/m_options.c
    trunk/coregrind/m_xtmemory.c
    trunk/docs/xml/manual-core-adv.xml
    trunk/docs/xml/manual-core.xml
    trunk/gdbserver_tests/mchelp.stdoutB.exp
    trunk/memcheck/docs/mc-manual.xml
    trunk/memcheck/mc_include.h
    trunk/memcheck/mc_leakcheck.c
    trunk/memcheck/mc_main.c

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Sat Jan 21 11:00:39 2017
@@ -24,6 +24,7 @@
    and 'massif format. The existing visualisers for these formats (e.g.
    callgrind_annotate, kcachegrind, ms_print) can be used to visualise
    and analyse these reports.
+   Memcheck can also produce leak reports in an xtree callgrind format.
    For more details, read the user manual.
 
 * ================== PLATFORM CHANGES =================
@@ -41,6 +42,13 @@
 
   - Support for --xtree-memory and 'xtmemory [<filename>]>'.
 
+  - New command line options --xtree-leak=no|yes and --xtree-leak-file=<file>
+    to produce the end of execution leak report in a xtree callgrind format
+    file.
+
+  - New option 'xtleak' in the memcheck leak_check monitor command, to
+    produce the leak report in an xtree file.
+
 * Massif:
 
   - Support for --xtree-memory and 'xtmemory [<filename>]>'.
@@ -68,6 +76,9 @@
   first line uniquely identifying the format ("# callgrind format").
   Callgrind creates this line now (also the new xtree functionality).
 
+* File name template arguments (such as --log-file, --xtree-memory-file, ...)
+  have a new %n format letter that is replaced by a sequence number.
+
 * ==================== FIXED BUGS ====================
 
 The following bugs have been fixed or resolved.  Note that "n-i-bz"

Modified: trunk/coregrind/m_options.c
==============================================================================
--- trunk/coregrind/m_options.c (original)
+++ trunk/coregrind/m_options.c Sat Jan 21 11:00:39 2017
@@ -226,6 +226,19 @@
             j += VG_(sprintf)(&out[j], "%d", pid);
             i++;
          }
+         else if ('n' == format[i]) {
+            // Print a seq nr.
+            static Int last_pid;
+            static Int seq_nr;
+            Int pid = VG_(getpid)();
+            if (last_pid != pid)
+               seq_nr = 0;
+            last_pid = pid;
+            seq_nr++;
+            ENSURE_THIS_MUCH_SPACE(10);
+            j += VG_(sprintf)(&out[j], "%d", seq_nr);
+            i++;
+         }
          else if ('q' == format[i]) {
             i++;
             if ('{' == format[i]) {

Modified: trunk/coregrind/m_xtmemory.c
==============================================================================
--- trunk/coregrind/m_xtmemory.c (original)
+++ trunk/coregrind/m_xtmemory.c Sat Jan 21 11:00:39 2017
@@ -288,7 +288,8 @@
       = VG_(expand_file_name)("--xtree-memory-file",
                               (filename == NULL) ?
                               (fini ?
-                               VG_(clo_xtree_memory_file) : "xtmemory.kcg")
+                               VG_(clo_xtree_memory_file)
+                               : "xtmemory.kcg.%p.%n")
                               : filename);
 
    /* fini is False => even if user kept --xtree-memory=none, we

Modified: trunk/docs/xml/manual-core-adv.xml
==============================================================================
--- trunk/docs/xml/manual-core-adv.xml (original)
+++ trunk/docs/xml/manual-core-adv.xml Sat Jan 21 11:00:39 2017
@@ -1397,7 +1397,7 @@
   </listitem>
 
   <listitem>
-    <para><varname>xtmemory [&lt;filename&gt; default xtmemory.kcg]</varname>
+    <para><varname>xtmemory [&lt;filename&gt; default xtmemory.kcg.%p.%n]</varname>
       requests the tool to produce an xtree heap memory report.
       See <xref linkend="manual-core.xtree"/> for
       a detailed explanation about execution trees. </para>

Modified: trunk/docs/xml/manual-core.xml
==============================================================================
--- trunk/docs/xml/manual-core.xml (original)
+++ trunk/docs/xml/manual-core.xml Sat Jan 21 11:00:39 2017
@@ -888,6 +888,12 @@
       all those processes will go into one file, possibly jumbled up, and
       possibly incomplete.</para>
 
+      <para><option>%n</option> is replaced with a file sequence number
+      unique for this process.
+      This is useful for processes that produces several files
+      from the same filename template.</para>
+
+
       <para><option>%q{FOO}</option> is replaced with the contents of the
       environment variable <varname>FOO</varname>.  If the
       <option>{FOO}</option> part is malformed, it causes an abort.  This
@@ -2747,7 +2753,9 @@
 <para>An execution tree (xtree) is made of a set of stack traces, each
   stack trace is associated with some resource consumptions or event
   counts.  Depending on the xtree, different event counts/resource
-  consumptions can be recorded in the xtree.</para>
+  consumptions can be recorded in the xtree. Multiple tools can
+  produce memory use xtree. Memcheck can output the leak search results
+  in an xtree.</para>
 
 <para> A typical usage for an xtree is to show a graphical or textual
   representation of the heap usage of a program. The below figure is

Modified: trunk/gdbserver_tests/mchelp.stdoutB.exp
==============================================================================
--- trunk/gdbserver_tests/mchelp.stdoutB.exp (original)
+++ trunk/gdbserver_tests/mchelp.stdoutB.exp Sat Jan 21 11:00:39 2017
@@ -27,12 +27,13 @@
   check_memory [addressable|defined] <addr> [<len>]
         check that <len> (or 1) bytes at <addr> have the given accessibility
             and outputs a description of <addr>
-  leak_check [full*|summary]
+  leak_check [full*|summary|xtleak]
                 [kinds kind1,kind2,...|reachable|possibleleak*|definiteleak]
                 [heuristics heur1,heur2,...]
                 [increased*|changed|any]
                 [unlimited*|limited <max_loss_records_output>]
             * = defaults
+         xtleak produces an xtree full leak result in xtleak.kcg.%p.%n
        where kind is one of:
          definite indirect possible reachable all none
        where heur is one of:
@@ -53,7 +54,7 @@
         (with len 1, only shows "start pointers" pointing exactly to <addr>,
          with len > 1, will also show "interior pointers")
   xtmemory [<filename>]
-        dump xtree memory profile in <filename> (default xtmemory.kcg)
+        dump xtree memory profile in <filename> (default xtmemory.kcg.%p.%n)
 general valgrind monitor commands:
   help [debug]            : monitor command help. With debug: + debugging commands
   v.wait [<ms>]           : sleep <ms> (default 0) then continue
@@ -98,12 +99,13 @@
   check_memory [addressable|defined] <addr> [<len>]
         check that <len> (or 1) bytes at <addr> have the given accessibility
             and outputs a description of <addr>
-  leak_check [full*|summary]
+  leak_check [full*|summary|xtleak]
                 [kinds kind1,kind2,...|reachable|possibleleak*|definiteleak]
                 [heuristics heur1,heur2,...]
                 [increased*|changed|any]
                 [unlimited*|limited <max_loss_records_output>]
             * = defaults
+         xtleak produces an xtree full leak result in xtleak.kcg.%p.%n
        where kind is one of:
          definite indirect possible reachable all none
        where heur is one of:
@@ -124,5 +126,5 @@
         (with len 1, only shows "start pointers" pointing exactly to <addr>,
          with len > 1, will also show "interior pointers")
   xtmemory [<filename>]
-        dump xtree memory profile in <filename> (default xtmemory.kcg)
+        dump xtree memory profile in <filename> (default xtmemory.kcg.%p.%n)
 monitor command request to kill this process

Modified: trunk/memcheck/docs/mc-manual.xml
==============================================================================
--- trunk/memcheck/docs/mc-manual.xml (original)
+++ trunk/memcheck/docs/mc-manual.xml Sat Jan 21 11:00:39 2017
@@ -880,6 +880,56 @@
     <para> Note that  <option>--show-possibly-lost=no</option> has no effect
       if <option>--show-reachable=yes</option> is specified.</para>
   </varlistentry>
+
+  <varlistentry id="opt.xtree-leak" xreflabel="--xtree-leak">
+    <term>
+      <option><![CDATA[--xtree-leak=<no|yes> [no] ]]></option>
+    </term>
+    <listitem>
+      <para>If set to yes, the results for the leak search done at exit will be
+       output in a 'Callgrind Format' execution tree file. The produced file
+       will contain the following events:</para>
+      <itemizedlist>
+        <listitem><para><option>RB</option> : Reachable Bytes</para></listitem>
+         <listitem><para><option>PB</option> : Possibly lost Bytes</para></listitem>
+         <listitem><para><option>IB</option> : Indirectly lost Bytes</para></listitem>
+         <listitem><para><option>DB</option> : Definitely lost Bytes (direct plus indirect)</para></listitem>
+         <listitem><para><option>DiB</option> : Definitely indirectly lost Bytes (subset of DB)</para></listitem>
+         <listitem><para><option>RBk</option> : reachable Blocks</para></listitem>
+         <listitem><para><option>PBk</option> : Possibly lost Blocks</para></listitem>
+         <listitem><para><option>IBk</option> : Indirectly lost Blocks</para></listitem>
+         <listitem><para><option>DBk</option> : Definitely lost Blocks</para></listitem>
+      </itemizedlist>
+      
+      <para>The increase or decrease for all events above will also be output in
+        the file to provide the delta (increase or decreaseà between 2
+        successive leak searches. For example, <option>iRB</option> is the
+        increase of the <option>RB</option> event, <option>dPBk</option> is the
+        decrease of <option>PBk</option> event. The values for the increase and
+        decrease events will be zero for the first leak search done.</para>
+      
+      <para>See <xref linkend="manual-core.xtree"/> for a detailed explanation
+        about execution trees.</para>
+    </listitem>
+  </varlistentry>
+  
+  <varlistentry id="opt.xtree-leak-file" xreflabel="--xtree-leak-file">
+    <term>
+      <option><![CDATA[--xtree-leak-file=<filename> [default:
+      xtleak.kcg.%p] ]]></option>
+    </term>
+    <listitem>
+      <para>Specifies that Valgrind should produce the xtree leak
+        report in the specified file.  Any <option>%p</option>,
+        <option>%q</option> or  <option>%n</option> sequences appearing in
+        the filename are expanded
+        in exactly the same way as they are for <option>--log-file</option>.
+        See the description of <xref linkend="opt.log-file"/>
+        for details. </para>
+      <para>See <xref linkend="manual-core.xtree"/>
+      for a detailed explanation about execution trees formats. </para>
+    </listitem>
+  </varlistentry>
   
   <varlistentry id="opt.undef-value-errors" xreflabel="--undef-value-errors">
     <term>
@@ -1834,7 +1884,7 @@
   </listitem>
 
   <listitem>
-    <para><varname>leak_check [full*|summary]
+    <para><varname>leak_check [full*|summary|xtleak]
                               [kinds &lt;set&gt;|reachable|possibleleak*|definiteleak]
                               [heuristics heur1,heur2,...]
                               [increased*|changed|any]
@@ -1843,7 +1893,7 @@
     performs a leak check. The <varname>*</varname> in the arguments
     indicates the default values. </para>
 
-    <para> If the <varname>[full*|summary]</varname> argument is
+    <para> If the <varname>[full*|summary|xtleak]</varname> argument is
     <varname>summary</varname>, only a summary of the leak search is given;
     otherwise a full leak report is produced.  A full leak report gives
     detailed information for each leak: the stack trace where the leaked blocks
@@ -1857,6 +1907,13 @@
     of leak records to output. If this maximum is reached, the leak
     search  outputs the records with the biggest number of bytes.
     </para>
+    <para>The value <varname>xtleak</varname> also produces a full leak report,
+      but output it as an xtree in a file xtleak.kcg.%p.%n (see <xref linkend="opt.log-file"/>).
+      See <xref linkend="manual-core.xtree"/>
+      for a detailed explanation about execution trees formats.
+      See <xref linkend="opt.xtree-leak"/> for the description of the events
+      in a xtree leak file.
+      </para>
 
     <para>The <varname>kinds</varname> argument controls what kind of blocks
     are shown for a <varname>full</varname> leak search.  The set of leak kinds

Modified: trunk/memcheck/mc_include.h
==============================================================================
--- trunk/memcheck/mc_include.h (original)
+++ trunk/memcheck/mc_include.h Sat Jan 21 11:00:39 2017
@@ -386,7 +386,7 @@
                         //   least one interior-pointer along the way.
       IndirectLeak =2,  // Leaked, but reachable from another leaked block
                         //   (be it Unreached or IndirectLeak).
-      Unreached    =3,  // Not reached, ie. leaked.
+      Unreached    =3   // Not reached, ie. leaked.
                         //   (At best, only reachable from itself via a cycle.)
   }
   Reachedness;
@@ -461,6 +461,7 @@
       LeakCheckDeltaMode deltamode;
       UInt max_loss_records_output; // limit on the nr of loss records output.
       Bool requested_by_monitor_command; // True when requested by gdb/vgdb.
+      const HChar* xt_filename; // if != NULL, produce an xtree leak file.
    }
    LeakCheckParams;
 

Modified: trunk/memcheck/mc_leakcheck.c
==============================================================================
--- trunk/memcheck/mc_leakcheck.c (original)
+++ trunk/memcheck/mc_leakcheck.c Sat Jan 21 11:00:39 2017
@@ -46,6 +46,8 @@
 #include "pub_tool_signals.h"       // Needed for mc_include.h
 #include "pub_tool_libcsetjmp.h"    // setjmp facilities
 #include "pub_tool_tooliface.h"     // Needed for mc_include.h
+#include "pub_tool_xarray.h"
+#include "pub_tool_xtree.h"
 
 #include "mc_include.h"
 
@@ -1301,6 +1303,189 @@
       && RiS(lr->key.state,lcp->errors_for_leak_kinds);
 }
 
+//
+// Types and functions for xtree leak report.
+//
+
+static XTree* leak_xt;
+
+/* Sizes and delta sizes for a loss record output in an xtree.
+   As the output format can only show positive values, we need values for
+   the increase and decrease cases. */
+typedef
+   struct _XT_BIBK {
+      ULong szB;           // Current values
+      ULong indirect_szB;
+      ULong num_blocks;
+   } XT_BIBK; // Bytes, Indirect bytes, BlocKs
+
+typedef
+   enum {
+      XT_Value    =0,
+      XT_Increase =1,
+      XT_Decrease =2
+  }
+  XT_VID; // Value or Increase or Decrease
+
+typedef
+   struct _XT_lr {
+      XT_BIBK vid[3]; // indexed by XT_VID
+   } XT_lr;
+
+typedef
+   struct _XT_Leak {
+      XT_lr xt_lr[4]; // indexed by Reachedness
+   } XT_Leak;
+
+static void MC_(XT_Leak_init)(void* xtl)
+{
+   VG_(memset) (xtl, 0, sizeof(XT_Leak));
+}
+static void MC_(XT_Leak_add) (void* to, const void* xtleak)
+{
+   XT_Leak* xto = to;
+   const XT_Leak* xtl = xtleak;
+
+   for (int r = Reachable; r <= Unreached; r++)
+      for (int d = 0; d < 3; d++) {
+         xto->xt_lr[r].vid[d].szB += xtl->xt_lr[r].vid[d].szB;
+         xto->xt_lr[r].vid[d].indirect_szB += xtl->xt_lr[r].vid[d].indirect_szB;
+         xto->xt_lr[r].vid[d].num_blocks += xtl->xt_lr[r].vid[d].num_blocks;
+      }
+}
+static void XT_insert_lr (LossRecord* lr)
+{
+   XT_Leak xtl;
+   Reachedness i = lr->key.state;
+
+   MC_(XT_Leak_init)(&xtl);
+  
+   xtl.xt_lr[i].vid[XT_Value].szB = lr->szB;
+   xtl.xt_lr[i].vid[XT_Value].indirect_szB = lr->indirect_szB;
+   xtl.xt_lr[i].vid[XT_Value].num_blocks = lr->num_blocks;
+
+   if (lr->szB > lr->old_szB)
+      xtl.xt_lr[i].vid[XT_Increase].szB = lr->szB - lr->old_szB;
+   else
+      xtl.xt_lr[i].vid[XT_Decrease].szB = lr->old_szB - lr->szB;
+   if (lr->indirect_szB > lr->old_indirect_szB)
+      xtl.xt_lr[i].vid[XT_Increase].indirect_szB
+         = lr->indirect_szB - lr->old_indirect_szB;
+   else
+      xtl.xt_lr[i].vid[XT_Decrease].indirect_szB
+         = lr->old_indirect_szB - lr->indirect_szB;
+   if (lr->num_blocks > lr->old_num_blocks)
+      xtl.xt_lr[i].vid[XT_Increase].num_blocks
+         = lr->num_blocks - lr->old_num_blocks;
+   else
+      xtl.xt_lr[i].vid[XT_Decrease].num_blocks
+         = lr->old_num_blocks - lr->num_blocks;
+
+   VG_(XT_add_to_ec)(leak_xt, lr->key.allocated_at, &xtl);
+}
+
+static void MC_(XT_Leak_sub) (void* from, const void* xtleak)
+{
+   tl_assert(0); // Should not be called.
+}
+static const HChar* MC_(XT_Leak_img) (const void* xtleak)
+{
+   static XT_Leak zero;
+   static HChar buf[600];
+   UInt off = 0;
+
+   const XT_Leak* xtl = xtleak;
+
+   if (VG_(memcmp)(xtl, &zero, sizeof(XT_Leak)) != 0) {
+      for (UInt d = XT_Value; d <= XT_Decrease; d++) {
+         // print szB. We add indirect_szB to have the Unreachable showing
+         // the total bytes loss, including indirect loss. This is similar
+         // to the textual and xml reports.
+         for (UInt r = Reachable; r <= Unreached; r++)
+            off += VG_(sprintf) (buf + off, " %llu",
+                                 xtl->xt_lr[r].vid[d].szB
+                                   + xtl->xt_lr[r].vid[d].indirect_szB);
+         // print indirect_szB, only for reachedness having such values)
+         for (UInt r = Reachable; r <= Unreached; r++)
+            if (r == Unreached)
+               off += VG_(sprintf) (buf + off, " %llu",
+                                    xtl->xt_lr[r].vid[d].indirect_szB);
+         // print num_blocks
+         for (UInt r = Reachable; r <= Unreached; r++)
+            off += VG_(sprintf) (buf + off, " %llu",
+                                 xtl->xt_lr[r].vid[d].num_blocks);
+      }
+      return buf + 1; // + 1 to skip the useless first space
+   } else {
+      return NULL;
+   }
+}
+
+/* The short event name is made of 2 or 3 or 4 letters:
+     an optional delta indication:  i = increase  d = decrease
+     a loss kind: R = Reachable P = Possibly I = Indirectly D = Definitely
+     an optional i to indicate this loss record has indirectly lost bytes
+     B = Bytes or Bk = Blocks.
+   Note that indirectly lost bytes/blocks can thus be counted in 2
+   loss records: the loss records for their "own" allocation stack trace,
+   and the loss record of the 'main' Definitely or Possibly loss record
+   in the indirectly lost count for these loss records. */
+static const HChar* XT_Leak_events =
+   ////// XT_Value szB
+   "RB : Reachable Bytes"                                  ","
+   "PB : Possibly lost Bytes"                              ","
+   "IB : Indirectly lost Bytes"                            ","
+   "DB : Definitely lost Bytes (direct plus indirect)"     ","
+
+   ////// XT_Value indirect_szB
+   // no RiB
+   // no PiB
+   // no IiB
+   "DiB : Definitely indirectly lost Bytes (subset of DB)" ","
+
+   ////// XT_Value num_blocks
+   "RBk : reachable Blocks"                                ","
+   "PBk : Possibly lost Blocks"                            ","
+   "IBk : Indirectly lost Blocks"                          ","
+   "DBk : Definitely lost Blocks"                          ","
+
+   ////// XT_Increase szB
+   "iRB : increase Reachable Bytes"                        ","
+   "iPB : increase Possibly lost Bytes"                    ","
+   "iIB : increase Indirectly lost Bytes"                  ","
+   "iDB : increase Definitely lost Bytes"                  ","
+
+   ////// XT_Increase indirect_szB
+   // no iRiB
+   // no iPiB
+   // no iIiB
+   "iDiB : increase Definitely indirectly lost Bytes"      ","
+
+   ////// XT_Increase num_blocks
+   "iRBk : increase reachable Blocks"                      ","
+   "iPBk : increase Possibly lost Blocks"                  ","
+   "iIBk : increase Indirectly lost Blocks"                ","
+   "iDBk : increase Definitely lost Blocks"                ","
+
+
+   ////// XT_Decrease szB
+   "dRB : decrease Reachable Bytes"                        ","
+   "dPB : decrease Possibly lost Bytes"                    ","
+   "dIB : decrease Indirectly lost Bytes"                  ","
+   "dDB : decrease Definitely lost Bytes"                  ","
+
+   ////// XT_Decrease indirect_szB
+   // no dRiB
+   // no dPiB
+   // no dIiB
+   "dDiB : decrease Definitely indirectly lost Bytes"      ","
+
+   ////// XT_Decrease num_blocks
+   "dRBk : decrease reachable Blocks"                      ","
+   "dPBk : decrease Possibly lost Blocks"                  ","
+   "dIBk : decrease Indirectly lost Blocks"                ","
+   "dDBk : decrease Definitely lost Blocks";
+
 static void print_results(ThreadId tid, LeakCheckParams* lcp)
 {
    Int          i, n_lossrecords, start_lr_output_scan;
@@ -1452,14 +1637,28 @@
       }
    }
 
+   if (lcp->xt_filename != NULL)
+      leak_xt = VG_(XT_create) (VG_(malloc),
+                                "mc_leakcheck.leak_xt",
+                                VG_(free),
+                                sizeof(XT_Leak),
+                                MC_(XT_Leak_init),
+                                MC_(XT_Leak_add),
+                                MC_(XT_Leak_sub),
+                                VG_(XT_filter_maybe_below_main));
+
    // Print the loss records (in size order) and collect summary stats.
    for (i = start_lr_output_scan; i < n_lossrecords; i++) {
       Bool count_as_error, print_record;
       lr = lr_array[i];
       get_printing_rules(lcp, lr, &count_as_error, &print_record);
       is_suppressed =
-         MC_(record_leak_error) ( tid, i+1, n_lossrecords, lr, print_record,
-                                  count_as_error );
+         MC_(record_leak_error)
+           ( tid, i+1, n_lossrecords, lr,
+             lcp->xt_filename == NULL ? print_record : False,
+             count_as_error );
+      if (lcp->xt_filename != NULL && !is_suppressed && print_record)
+         XT_insert_lr (lr);
 
       if (is_suppressed) {
          MC_(blocks_suppressed) += lr->num_blocks;
@@ -1486,6 +1685,14 @@
       }
    }
 
+   if (lcp->xt_filename != NULL) {
+      VG_(XT_callgrind_print)(leak_xt,
+                              lcp->xt_filename,
+                              XT_Leak_events,
+                              MC_(XT_Leak_img));
+      VG_(XT_delete)(leak_xt);
+   }
+
    if (VG_(clo_verbosity) > 0 && !VG_(clo_xml)) {
       HChar d_bytes[31];
       HChar d_blocks[31];

Modified: trunk/memcheck/mc_main.c
==============================================================================
--- trunk/memcheck/mc_main.c (original)
+++ trunk/memcheck/mc_main.c Sat Jan 21 11:00:39 2017
@@ -6012,6 +6012,8 @@
                                                 | H2S( LchLength64)
                                                 | H2S( LchNewArray)
                                                 | H2S( LchMultipleInheritance);
+Bool          MC_(clo_xtree_leak)             = False;
+const HChar*  MC_(clo_xtree_leak_file) = "xtleak.kcg.%p";
 Bool          MC_(clo_workaround_gcc296_bugs) = False;
 Int           MC_(clo_malloc_fill)            = -1;
 Int           MC_(clo_free_fill)              = -1;
@@ -6213,6 +6215,11 @@
    else if VG_BOOL_CLO(arg, "--expensive-definedness-checks",
                        MC_(clo_expensive_definedness_checks)) {}
 
+   else if VG_BOOL_CLO(arg, "--xtree-leak",
+                       MC_(clo_xtree_leak)) {}
+   else if VG_STR_CLO (arg, "--xtree-leak-file",
+                       MC_(clo_xtree_leak_file)) {}
+
    else
       return VG_(replacement_malloc_process_cmd_line_option)(arg);
 
@@ -6244,6 +6251,8 @@
 "                                     same as --show-leak-kinds=definite,possible\n"
 "    --show-reachable=no --show-possibly-lost=no\n"
 "                                     same as --show-leak-kinds=definite\n"
+"    --xtree-leak=no|yes              output leak result in xtree format? [no]\n"
+"    --xtree-leak-file=<file>         xtree leak report file [xtleak.kcg.%%p.%%n]\n"
 "    --undef-value-errors=no|yes      check for undefined value errors [yes]\n"
 "    --track-origins=no|yes           show origins of undefined values? [no]\n"
 "    --partial-loads-ok=no|yes        too hard to explain here; see manual [yes]\n"
@@ -6378,12 +6387,13 @@
 "  check_memory [addressable|defined] <addr> [<len>]\n"
 "        check that <len> (or 1) bytes at <addr> have the given accessibility\n"
 "            and outputs a description of <addr>\n"
-"  leak_check [full*|summary]\n"
+"  leak_check [full*|summary|xtleak]\n"
 "                [kinds kind1,kind2,...|reachable|possibleleak*|definiteleak]\n"
 "                [heuristics heur1,heur2,...]\n"
 "                [increased*|changed|any]\n"
 "                [unlimited*|limited <max_loss_records_output>]\n"
 "            * = defaults\n"
+"         xtleak produces an xtree full leak result in xtleak.kcg.%%p.%%n\n"
 "       where kind is one of:\n"
 "         definite indirect possible reachable all none\n"
 "       where heur is one of:\n"
@@ -6404,7 +6414,7 @@
 "        (with len 1, only shows \"start pointers\" pointing exactly to <addr>,\n"
 "         with len > 1, will also show \"interior pointers\")\n"
 "  xtmemory [<filename>]\n"
-"        dump xtree memory profile in <filename> (default xtmemory.kcg)\n"
+"        dump xtree memory profile in <filename> (default xtmemory.kcg.%%p.%%n)\n"
 "\n");
 }
 
@@ -6567,6 +6577,7 @@
    case  2: { /* leak_check */
       Int err = 0;
       LeakCheckParams lcp;
+      HChar* xt_filename = NULL;
       HChar* kw;
       
       lcp.mode               = LC_Full;
@@ -6576,12 +6587,13 @@
       lcp.deltamode          = LCD_Increased;
       lcp.max_loss_records_output = 999999999;
       lcp.requested_by_monitor_command = True;
+      lcp.xt_filename = NULL;
       
       for (kw = VG_(strtok_r) (NULL, " ", &ssaveptr);
            kw != NULL;
            kw = VG_(strtok_r) (NULL, " ", &ssaveptr)) {
          switch (VG_(keyword_id)
-                 ("full summary "
+                 ("full summary xtleak "
                   "kinds reachable possibleleak definiteleak "
                   "heuristics "
                   "increased changed any "
@@ -6593,7 +6605,14 @@
             lcp.mode = LC_Full; break;
          case  1: /* summary */
             lcp.mode = LC_Summary; break;
-         case  2: { /* kinds */
+         case  2: /* xtleak */
+            lcp.mode = LC_Full;
+            xt_filename
+               = VG_(expand_file_name)("--xtleak-mc_main.c",
+                                       "xtleak.kcg.%p.%n");
+            lcp.xt_filename = xt_filename;
+            break;
+         case  3: { /* kinds */
             wcmd = VG_(strtok_r) (NULL, " ", &ssaveptr);
             if (wcmd == NULL
                 || !VG_(parse_enum_set)(MC_(parse_leak_kinds_tokens),
@@ -6605,17 +6624,17 @@
             }
             break;
          }
-         case  3: /* reachable */
+         case  4: /* reachable */
             lcp.show_leak_kinds = MC_(all_Reachedness)();
             break;
-         case  4: /* possibleleak */
+         case  5: /* possibleleak */
             lcp.show_leak_kinds
                = R2S(Possible) | R2S(IndirectLeak) | R2S(Unreached);
             break;
-         case  5: /* definiteleak */
+         case  6: /* definiteleak */
             lcp.show_leak_kinds = R2S(Unreached);
             break;
-         case  6: { /* heuristics */
+         case  7: { /* heuristics */
             wcmd = VG_(strtok_r) (NULL, " ", &ssaveptr);
             if (wcmd == NULL
                 || !VG_(parse_enum_set)(MC_(parse_leak_heuristics_tokens),
@@ -6627,15 +6646,15 @@
             }
             break;
          }
-         case  7: /* increased */
+         case  8: /* increased */
             lcp.deltamode = LCD_Increased; break;
-         case  8: /* changed */
+         case  9: /* changed */
             lcp.deltamode = LCD_Changed; break;
-         case  9: /* any */
+         case 10: /* any */
             lcp.deltamode = LCD_Any; break;
-         case 10: /* unlimited */
+         case 11: /* unlimited */
             lcp.max_loss_records_output = 999999999; break;
-         case 11: { /* limited */
+         case 12: { /* limited */
             Int int_value;
             const HChar* endptr;
 
@@ -6663,6 +6682,8 @@
       }
       if (!err)
          MC_(detect_memory_leaks)(tid, &lcp);
+      if (xt_filename != NULL)
+         VG_(free)(xt_filename);
       return True;
    }
       
@@ -6990,6 +7011,7 @@
          }
          lcp.max_loss_records_output = 999999999;
          lcp.requested_by_monitor_command = False;
+         lcp.xt_filename = NULL;
         
          MC_(detect_memory_leaks)(tid, &lcp);
          *ret = 0; /* return value is meaningless */
@@ -8025,6 +8047,7 @@
 
    if (MC_(clo_leak_check) != LC_Off) {
       LeakCheckParams lcp;
+      HChar* xt_filename = NULL;
       lcp.mode = MC_(clo_leak_check);
       lcp.show_leak_kinds = MC_(clo_show_leak_kinds);
       lcp.heuristics = MC_(clo_leak_check_heuristics);
@@ -8032,7 +8055,16 @@
       lcp.deltamode = LCD_Any;
       lcp.max_loss_records_output = 999999999;
       lcp.requested_by_monitor_command = False;
+      if (MC_(clo_xtree_leak)) {
+         xt_filename = VG_(expand_file_name)("--xtree-leak-file",
+                                             MC_(clo_xtree_leak_file));
+         lcp.xt_filename = xt_filename;
+      }
+      else
+         lcp.xt_filename = NULL;
       MC_(detect_memory_leaks)(1/*bogus ThreadId*/, &lcp);
+      if (MC_(clo_xtree_leak))
+         VG_(free)(xt_filename);
    } else {
       if (VG_(clo_verbosity) == 1 && !VG_(clo_xml)) {
          VG_(umsg)(


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Valgrind-developers mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/valgrind-developers