]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix 350202 - Add limited param to 'monitor block_list'
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Thu, 13 Aug 2015 22:49:32 +0000 (22:49 +0000)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Thu, 13 Aug 2015 22:49:32 +0000 (22:49 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15540

NEWS
docs/internals/3_10_BUGSTATUS.txt
gdbserver_tests/mchelp.stdoutB.exp
memcheck/docs/mc-manual.xml
memcheck/mc_include.h
memcheck/mc_leakcheck.c
memcheck/mc_main.c

diff --git a/NEWS b/NEWS
index b37e87b1f77063124ed2925c595b20582369aa1c..3057e15982ced1d2b0d1f2119972da4c68ced5ae 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,9 @@ Release 3.11.0 is under development, not yet released.
     get_vbits (in particular on little endian computers) when you need to
     associate byte data value with their corresponding validity bits.
 
+  - The 'block_list' monitor command now accepts an optional argument
+    'limited <max_blocks>' to control the nr of block addresses printed.
+
 * Massif:
   - New monitor command 'all_snapshots <filename>' that dumps all snapshots
     taken so far.
@@ -282,6 +285,7 @@ where XXXXXX is the bug number as listed below.
 349874  Fix typos in source code
 349828  memcpy intercepts memmove causing src/dst overlap error (ppc64 ld.so)
 349941  di_notify_mmap might create wrong start/size DebugInfoMapping
+350202  Add limited param to 'monitor block_list'
 350809  Fix none/tests/async-sigs for Solaris
 350811  Remove reference to --db-attach which has been removed.
 350813  Use handwritten memcheck assembly helpers on x86/Solaris in addition to {arm,x86}-linux
index caf111c9e440139b10c55f7d5db40da5333e9191..0a7708c94fbc413b87ae235ef461f431a2b058dd 100644 (file)
@@ -364,8 +364,6 @@ go in here.
 
 348358  describe should show info about main stack guard page
 
-350202  Add limited param to 'monitor block_list'
-
 === Output =============================================================
 
 339405  Adds ability to invoke a script in order to determine a
index 4e057ad03195de34addecbfd00109ccefa21d953..77d1eb182a2d967a39b2e1cd53e326255b4b301b 100644 (file)
@@ -41,8 +41,9 @@ memcheck monitor commands:
                  leak_check summary any
                  leak_check full kinds indirect,possible
                  leak_check full reachable any limited 100
-  block_list <loss_record_nr>
+  block_list <loss_record_nr> [unlimited*|limited <max_blocks>]
         after a leak search, shows the list of blocks of <loss_record_nr>
+            * = defaults
   who_points_at <addr> [<len>]
         shows places pointing inside <len> (default 1) bytes at <addr>
         (with len 1, only shows "start pointers" pointing exactly to <addr>,
@@ -105,8 +106,9 @@ memcheck monitor commands:
                  leak_check summary any
                  leak_check full kinds indirect,possible
                  leak_check full reachable any limited 100
-  block_list <loss_record_nr>
+  block_list <loss_record_nr> [unlimited*|limited <max_blocks>]
         after a leak search, shows the list of blocks of <loss_record_nr>
+            * = defaults
   who_points_at <addr> [<len>]
         shows places pointing inside <len> (default 1) bytes at <addr>
         (with len 1, only shows "start pointers" pointing exactly to <addr>,
index d38477019469381530f9b9124400a90ea50e1c0f..330355440f646619d532ac965d19b953dbd58e2f 100644 (file)
@@ -1886,8 +1886,12 @@ Address 0x8049E28 len 1 defined
   </listitem>
 
   <listitem>
-    <para><varname>block_list &lt;loss_record_nr&gt; </varname>
-    shows the list of blocks belonging to &lt;loss_record_nr&gt;.
+    <para><varname>block_list &lt;loss_record_nr&gt;
+                              [unlimited*|limited &lt;max_blocks&gt;]</varname>
+      shows the list of blocks belonging to &lt;loss_record_nr&gt;.
+      The nr of blocks to print can be controlled using the
+      <varname>limited</varname> argument followed by the maximum nr
+      of blocks to output.
     </para>
 
     <para> A leak search merges the allocated blocks in loss records :
index 3493fb5bcd5d4eab97e2b99be73c15a605ae63ea..991c5b94cc2d3580f0402f70f5588811dd926729 100644 (file)
@@ -461,9 +461,10 @@ extern UInt MC_(leak_search_gen);
 extern LeakCheckDeltaMode MC_(detect_memory_leaks_last_delta_mode);
 
 // prints the list of blocks corresponding to the given loss_record_nr.
+// (up to maximum max_blocks)
 // Returns True if loss_record_nr identifies a correct loss record from last
 // leak search, returns False otherwise.
-Bool MC_(print_block_list) ( UInt loss_record_nr);
+Bool MC_(print_block_list) ( UInt loss_record_nr, UInt max_blocks);
 
 // Prints the addresses/registers/... at which a pointer to
 // the given range [address, address+szB[ is found.
index 84d4688684bb807afd1320841ce86432783575d1..db317f75f74e485c08a4baa045cb77a48d58ceb7 100644 (file)
@@ -1507,14 +1507,15 @@ static void print_results(ThreadId tid, LeakCheckParams* lcp)
 }
 
 // print recursively all indirectly leaked blocks collected in clique.
-static void print_clique (Int clique, UInt level)
+// Printing stops when *remaining reaches 0.
+static void print_clique (Int clique, UInt level, UInt *remaining)
 {
    Int ind;
    UInt i,  n_lossrecords;
 
    n_lossrecords = VG_(OSetGen_Size)(lr_table);
 
-   for (ind = 0; ind < lc_n_chunks; ind++) {
+   for (ind = 0; ind < lc_n_chunks && *remaining > 0; ind++) {
       LC_Extra*     ind_ex = &(lc_extras)[ind];
       if (ind_ex->state == IndirectLeak 
           && ind_ex->IorC.clique == (SizeT) clique) {
@@ -1533,19 +1534,21 @@ static void print_clique (Int clique, UInt level)
          VG_(umsg)("%p[%lu] indirect loss record %u\n",
                    (void *)ind_ch->data, (SizeT)ind_ch->szB,
                    lr_i+1); // lr_i+1 for user numbering.
+         (*remaining)--;
          if (lr_i >= n_lossrecords)
             VG_(umsg)
                ("error: no indirect loss record found for %p[%lu]?????\n",
                 (void *)ind_ch->data, (SizeT)ind_ch->szB);
-         print_clique(ind, level+1);
+         print_clique(ind, level+1, remaining);
       }
    }
  }
 
-Bool MC_(print_block_list) ( UInt loss_record_nr)
+Bool MC_(print_block_list) ( UInt loss_record_nr, UInt max_blocks)
 {
    UInt         i,  n_lossrecords;
    LossRecord*  lr;
+   UInt remaining = max_blocks;
 
    if (lr_table == NULL || lc_chunks == NULL || lc_extras == NULL) {
       VG_(umsg)("Can't print block list : no valid leak search result\n");
@@ -1569,7 +1572,7 @@ Bool MC_(print_block_list) ( UInt loss_record_nr)
    MC_(pp_LossRecord)(loss_record_nr+1, n_lossrecords, lr);
 
    // Match the chunks with loss records.
-   for (i = 0; i < lc_n_chunks; i++) {
+   for (i = 0; i < lc_n_chunks && remaining > 0; i++) {
       MC_Chunk*     ch = lc_chunks[i];
       LC_Extra*     ex = &(lc_extras)[i];
       LossRecord*   old_lr;
@@ -1584,6 +1587,7 @@ Bool MC_(print_block_list) ( UInt loss_record_nr)
          if (old_lr == lr_array[loss_record_nr]) {
             VG_(umsg)("%p[%lu]\n",
                       (void *)ch->data, (SizeT)ch->szB);
+            remaining--;
             if (ex->state != Reachable) {
                // We can print the clique in all states, except Reachable.
                // In Unreached state, lc_chunk[i] is the clique leader.
@@ -1591,7 +1595,7 @@ Bool MC_(print_block_list) ( UInt loss_record_nr)
                // which was later collected in another clique.
                // For Possible, lc_chunk[i] might be the top of a clique
                // or an intermediate clique.
-               print_clique(i, 1);
+               print_clique(i, 1, &remaining);
             }
          }
       } else {
index 14a1d6ade0f2e9378ee4ec825aeca6385205c749..c0d3417e3c701456402528499e41948dc7c9064f 100644 (file)
@@ -6038,8 +6038,9 @@ static void print_monitor_help ( void )
 "                 leak_check summary any\n"
 "                 leak_check full kinds indirect,possible\n"
 "                 leak_check full reachable any limited 100\n"
-"  block_list <loss_record_nr>\n"
+"  block_list <loss_record_nr> [unlimited*|limited <max_blocks>]\n"
 "        after a leak search, shows the list of blocks of <loss_record_nr>\n"
+"            * = defaults\n"
 "  who_points_at <addr> [<len>]\n"
 "        shows places pointing inside <len> (default 1) bytes at <addr>\n"
 "        (with len 1, only shows \"start pointers\" pointing exactly to <addr>,\n"
@@ -6322,16 +6323,53 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
    case  5: { /* block_list */
       HChar* wl;
       HChar *endptr;
+      HChar *the_end;
       UInt lr_nr = 0;
+
       wl = VG_(strtok_r) (NULL, " ", &ssaveptr);
       if (wl != NULL)
          lr_nr = VG_(strtoull10) (wl, &endptr);
       if (wl == NULL || *endptr != '\0') {
          VG_(gdb_printf) ("malformed or missing integer\n");
       } else {
+         UInt limit_blocks;
+         Int int_value;
+
+         wl = VG_(strtok_r) (NULL, " ", &ssaveptr);
+         if (wl != NULL) {
+            switch (VG_(keyword_id) ("unlimited limited ", 
+                                     wl,  kwd_report_all)) {
+            case -2: return True;
+            case -1: return True;
+            case  0: /* unlimited */
+               limit_blocks = 999999999; break;
+            case  1: /* limited */
+               wcmd = VG_(strtok_r) (NULL, " ", &ssaveptr);
+               if (wcmd == NULL) {
+                  VG_(gdb_printf) ("missing integer value\n");
+                  return True;
+               }
+               int_value = VG_(strtoll10) (wcmd, &the_end);
+               if (*the_end != '\0') {
+                  VG_(gdb_printf) ("malformed integer value\n");
+                  return True;
+               }
+               if (int_value <= 0) {
+                  VG_(gdb_printf) ("max_blocks must be >= 1,"
+                                   " got %d\n", int_value);
+                  return True;
+               }
+               limit_blocks = (UInt) int_value;
+               break;
+            default:
+               tl_assert (0);
+            }
+         } else {
+            limit_blocks = 999999999;
+         }
          /* lr_nr-1 as what is shown to the user is 1 more than the index
             in lr_array. */
-         if (lr_nr == 0 || ! MC_(print_block_list) (lr_nr-1))
+         if (lr_nr == 0 || ! MC_(print_block_list) (lr_nr-1, limit_blocks))
             VG_(gdb_printf) ("invalid loss record nr\n");
       }
       return True;