]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
* Memcheck:
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Tue, 4 Aug 2015 19:11:03 +0000 (19:11 +0000)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Tue, 4 Aug 2015 19:11:03 +0000 (19:11 +0000)
  - A new monitor command 'xb <addr> <len>' shows the validity bits
    of <len> bytes at <addr>. Below the validity bits, the byte
    values are shown using a layout similar to the GDB command
    'x /<len>xb <addr>'. The monitor command 'xb' is easier to use
    (in particular on little endian computers) when you need to associate
    byte data value with their corresponding validity bits.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15483

NEWS
gdbserver_tests/mchelp.stdoutB.exp
memcheck/docs/mc-manual.xml
memcheck/mc_main.c

diff --git a/NEWS b/NEWS
index 71f120e1f6ff6bdc06b96a811411cb855334cdbe..608d7a5669470d29359da8b007afb64e954d5044 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,12 @@ Release 3.11.0 is under development, not yet released.
 * ==================== TOOL CHANGES ====================
 
 * Memcheck:
+  - A new monitor command 'xb <addr> <len>' shows the validity bits
+    of <len> bytes at <addr>. Below the validity bits, the byte
+    values are shown using a layout similar to the GDB command
+    'x /<len>xb <addr>'. The monitor command 'xb' is easier to use
+    (in particular on little endian computers) when you need to associate
+    byte data value with their corresponding validity bits.
 
 * Massif:
   - New monitor command 'all_snapshots <filename>' that dumps all snapshots
index a75ae42dbeebe24110c1fdffe04000098836be35..4e057ad03195de34addecbfd00109ccefa21d953 100644 (file)
@@ -13,10 +13,14 @@ general valgrind monitor commands:
   v.set merge-recursive-frames <num> : merge recursive calls in max <num> frames
   v.set vgdb-error <errornr> : debug me at error >= <errornr> 
 memcheck monitor commands:
-  get_vbits <addr> [<len>]
-        returns validity bits for <len> (or 1) bytes at <addr>
+  xb <addr> [<len>]
+        prints validity bits for <len> (or 1) bytes at <addr>
             bit values 0 = valid, 1 = invalid, __ = unaddressable byte
-        Example: get_vbits 0x........ 10
+        Then prints the bytes values below the corresponding validity bits
+        in a layout similar to the gdb command 'x /<len>xb <addr>'
+        Example: xb 0x........ 10
+  get_vbits <addr> [<len>]
+        Similar to xb, but only prints the validity bytes by group of 4.
   make_memory [noaccess|undefined
                      |defined|Definedifaddressable] <addr> [<len>]
         mark <len> (or 1) bytes at <addr> with the given accessibility
@@ -73,10 +77,14 @@ debugging valgrind internals monitor commands:
     (default traceflags 0b00100000 : show after instrumentation)
    An additional flag  0b100000000 allows to show gdbserver instrumentation
 memcheck monitor commands:
-  get_vbits <addr> [<len>]
-        returns validity bits for <len> (or 1) bytes at <addr>
+  xb <addr> [<len>]
+        prints validity bits for <len> (or 1) bytes at <addr>
             bit values 0 = valid, 1 = invalid, __ = unaddressable byte
-        Example: get_vbits 0x........ 10
+        Then prints the bytes values below the corresponding validity bits
+        in a layout similar to the gdb command 'x /<len>xb <addr>'
+        Example: xb 0x........ 10
+  get_vbits <addr> [<len>]
+        Similar to xb, but only prints the validity bytes by group of 4.
   make_memory [noaccess|undefined
                      |defined|Definedifaddressable] <addr> [<len>]
         mark <len> (or 1) bytes at <addr> with the given accessibility
index 7d84dc560f5885b746ecb1a0288d767cc0c6a294..d38477019469381530f9b9124400a90ea50e1c0f 100644 (file)
@@ -1648,36 +1648,51 @@ built-in gdbserver (see <xref linkend="manual-core-adv.gdbserver-commandhandling
 
 <itemizedlist>
   <listitem>
-    <para><varname>get_vbits &lt;addr&gt; [&lt;len&gt;]</varname>
-    shows the definedness (V) bits for &lt;len&gt; (default 1) bytes
-    starting at &lt;addr&gt;.  The definedness of each byte in the
-    range is given using two hexadecimal digits.  These hexadecimal
-    digits encode the validity of each bit of the corresponding byte,
-    using 0 if the bit is defined and 1 if the bit is undefined.
-    If a byte is not addressable, its validity bits are replaced
-    by <varname>__</varname> (a double underscore).
+    <para><varname>xb &lt;addr&gt; [&lt;len&gt;]</varname>
+      shows the definedness (V) bits and values for &lt;len&gt; (default 1)
+      bytes starting at &lt;addr&gt;.
+      For each 8 bytes, two lines are output.
+    </para>
+    <para>
+      The first line shows the validity bits for 8 bytes.
+      The definedness of each byte in the range is given using two hexadecimal
+      digits.  These hexadecimal digits encode the validity of each bit of the
+      corresponding byte,
+      using 0 if the bit is defined and 1 if the bit is undefined.
+      If a byte is not addressable, its validity bits are replaced
+      by <varname>__</varname> (a double underscore).
+    </para>
+    <para>
+      The second line shows the values of the bytes below the corresponding
+      validity bits. The format used to show the bytes data is similar to the
+      GDB command 'x /&lt;len&gt;xb &lt;addr&gt;'. The value for a non
+      addressable bytes is shown as ?? (two question marks).
     </para>
     <para>
-    In the following example, <varname>string10</varname> is an array
-    of 10 characters, in which the even numbered bytes are
-    undefined. In the below example, the byte corresponding
-    to <varname>string10[5]</varname> is not addressable.
+      In the following example, <varname>string10</varname> is an array
+      of 10 characters, in which the even numbered bytes are
+      undefined. In the below example, the byte corresponding
+      to <varname>string10[5]</varname> is not addressable.
     </para>
 <programlisting><![CDATA[
 (gdb) p &string10
-$4 = (char (*)[10]) 0x8049e28
-(gdb) monitor get_vbits 0x8049e28 10
-ff00ff00 ff__ff00 ff00
-(gdb) 
+$4 = (char (*)[10]) 0x804a2f0
+(gdb) mo xb 0x804a2f0 10
+                  ff      00      ff      00      ff      __      ff      00
+0x804A2F0:      0x3f    0x6e    0x3f    0x65    0x3f    0x??     0x3f    0x65
+                  ff      00
+0x804A2F8:      0x3f    0x00
+Address 0x804A2F0 len 10 has 1 bytes unaddressable
+(gdb)
 ]]></programlisting>
 
-    <para> The command get_vbits cannot be used with registers. To get
-    the validity bits of a register, you must start Valgrind with the
-    option <option>--vgdb-shadow-registers=yes</option>. The validity
-    bits of a register can be obtained by printing the 'shadow 1'
-    corresponding register.  In the below x86 example, the register
-    eax has all its bits undefined, while the register ebx is fully
-    defined.
+    <para> The command xb cannot be used with registers. To get
+      the validity bits of a register, you must start Valgrind with the
+      option <option>--vgdb-shadow-registers=yes</option>. The validity
+      bits of a register can then be obtained by printing the 'shadow 1'
+      corresponding register.  In the below x86 example, the register
+      eax has all its bits undefined, while the register ebx is fully
+      defined.
     </para>
 <programlisting><![CDATA[
 (gdb) p /x $eaxs1
@@ -1689,6 +1704,31 @@ $10 = 0x0
 
   </listitem>
 
+  <listitem>
+    <para><varname>get_vbits &lt;addr&gt; [&lt;len&gt;]</varname>
+    shows the definedness (V) bits for &lt;len&gt; (default 1) bytes
+    starting at &lt;addr&gt; using the same convention as the
+    <varname>xb</varname> command. <varname>get_vbits</varname> only
+    shows the V bits (grouped by 4 bytes). It does not show the values.
+    If you want to associate V bits with the corresponding byte values, the
+    <varname>xb</varname> command will be easier to use, in particular
+    on little endian computers when associating undefined parts of an integer
+    with their V bits values.
+    </para>
+    <para>
+    The following example shows the result of <varname>get_vibts</varname>
+    on the <varname>string10</varname> used in the  <varname>xb</varname>
+    command explanation.
+    </para>
+<programlisting><![CDATA[
+(gdb) monitor get_vbits 0x804a2f0 10
+ff00ff00 ff__ff00 ff00
+Address 0x804A2F0 len 10 has 1 bytes unaddressable
+(gdb) 
+]]></programlisting>
+
+  </listitem>
+
   <listitem>
     <para><varname>make_memory
     [noaccess|undefined|defined|Definedifaddressable] &lt;addr&gt;
index deadd314194afefa37a3888ab71ae313ff89fb40..78120813c28011d2b57c178ee7064bc8d41d3134 100644 (file)
@@ -6010,10 +6010,14 @@ static void print_monitor_help ( void )
       (
 "\n"
 "memcheck monitor commands:\n"
-"  get_vbits <addr> [<len>]\n"
-"        returns validity bits for <len> (or 1) bytes at <addr>\n"
+"  xb <addr> [<len>]\n"
+"        prints validity bits for <len> (or 1) bytes at <addr>\n"
 "            bit values 0 = valid, 1 = invalid, __ = unaddressable byte\n"
-"        Example: get_vbits 0x8049c78 10\n"
+"        Then prints the bytes values below the corresponding validity bits\n"
+"        in a layout similar to the gdb command 'x /<len>xb <addr>'\n"
+"        Example: xb 0x8049c78 10\n"
+"  get_vbits <addr> [<len>]\n"
+"        Similar to xb, but only prints the validity bytes by group of 4.\n"
 "  make_memory [noaccess|undefined\n"
 "                     |defined|Definedifaddressable] <addr> [<len>]\n"
 "        mark <len> (or 1) bytes at <addr> with the given accessibility\n"
@@ -6043,6 +6047,28 @@ static void print_monitor_help ( void )
 "\n");
 }
 
+/* Print szB bytes at address, with a format similar to the gdb command
+   x /<szB>xb address.
+   res[i] == 1 indicates the corresponding byte is addressable. */
+static void gdb_xb (Addr address, SizeT szB, Int res[])
+{
+   UInt i;
+
+   for (i = 0; i < szB; i++) {
+      UInt bnr = i % 8;
+      if (bnr == 0) {
+         if (i != 0)
+            VG_(printf) ("\n"); // Terminate previous line
+         VG_(printf) ("%p:", (void*)(address+i));
+      }
+      if (res[i] == 1)
+         VG_(printf) ("\t0x%02x", *(UChar*)(address+i));
+      else
+         VG_(printf) ("\t0x??");
+   }
+   VG_(printf) ("\n"); // Terminate previous line
+}
+
 /* return True if request recognised, False otherwise */
 static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
 {
@@ -6058,7 +6084,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
       command. This ensures a shorter abbreviation for the user. */
    switch (VG_(keyword_id) 
            ("help get_vbits leak_check make_memory check_memory "
-            "block_list who_points_at", 
+            "block_list who_points_at xb", 
             wcmd, kwd_report_duplicated_matches)) {
    case -2: /* multiple matches */
       return True;
@@ -6191,8 +6217,8 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
             else if (int_value > 0)
                lcp.max_loss_records_output = (UInt) int_value;
             else
-               VG_(gdb_printf) ("max_loss_records_output must be >= 1, got %d\n",
-                                int_value);
+               VG_(gdb_printf) ("max_loss_records_output must be >= 1,"
+                                " got %d\n", int_value);
             break;
          }
          default:
@@ -6303,7 +6329,8 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
       if (wl == NULL || *endptr != '\0') {
          VG_(gdb_printf) ("malformed or missing integer\n");
       } else {
-         // lr_nr-1 as what is shown to the user is 1 more than the index in lr_array.
+         /* 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))
             VG_(gdb_printf) ("invalid loss record nr\n");
       }
@@ -6324,6 +6351,52 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
       return True;
    }
 
+   case  7: { /* xb */
+      Addr address;
+      SizeT szB = 1;
+      if (VG_(strtok_get_address_and_size) (&address, &szB, &ssaveptr)) {
+         UChar vbits[8];
+         Int res[8];
+         Int i;
+         Int unaddressable = 0;
+         for (i = 0; i < szB; i++) {
+            Int bnr = i % 8;
+            res[bnr] = mc_get_or_set_vbits_for_client 
+               (address+i, (Addr) &vbits[bnr], 1, 
+                False, /* get them */
+                False  /* is client request */ ); 
+            /* We going to print the first vabits of a new line.
+               Terminate the previous line if needed: prints a line with the
+               address and the data. */
+            if (bnr == 0) {
+               if (i != 0) {
+                  VG_(printf) ("\n");
+                  gdb_xb (address + i - 8, 8, res);
+               }
+               VG_(printf) ("\t"); // To align VABITS with gdb_xb layout
+            }
+            if (res[bnr] == 1) {
+               VG_(printf) ("\t  %02x", vbits[bnr]);
+            } else {
+               tl_assert(3 == res[bnr]);
+               unaddressable++;
+               VG_(printf) ("\t  __");
+            }
+         }
+         VG_(printf) ("\n");
+         if (szB % 8 == 0 && szB > 0)
+            gdb_xb (address + szB - 8, 8, res);
+         else
+            gdb_xb (address + szB - szB % 8, szB % 8, res);
+         if (unaddressable) {
+            VG_(printf)
+               ("Address %p len %ld has %d bytes unaddressable\n",
+                (void *)address, szB, unaddressable);
+         }
+      }
+      return True;
+   }
+
    default: 
       tl_assert(0);
       return False;