]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add a gdbxrv monitor command to print the CFI unwind info for an address+len
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Tue, 2 Jun 2015 22:09:42 +0000 (22:09 +0000)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Tue, 2 Jun 2015 22:09:42 +0000 (22:09 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15306

coregrind/m_debuginfo/debuginfo.c
coregrind/m_debuginfo/storage.c
coregrind/m_gdbserver/server.c
coregrind/pub_core_debuginfo.h
docs/xml/manual-core-adv.xml
gdbserver_tests/mchelp.stdoutB.exp

index 15f1603505a64289ac948c13dc7f7c865a08369d..0dc78a342000795d6b3e79863aff442c15f826c8 100644 (file)
@@ -2828,6 +2828,37 @@ Addr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp,
 #  endif
 }
 
+void VG_(ppUnwindInfo) (Addr from, Addr to)
+{
+   DebugInfo*         di;
+   CFSI_m_CacheEnt*   ce;
+   Addr ce_from;
+   CFSI_m_CacheEnt*   next_ce;
+
+
+   ce = cfsi_m_cache__find(from);
+   ce_from = from;
+   while (from <= to) {
+      from++;
+      next_ce = cfsi_m_cache__find(from);
+      if ((ce == NULL && next_ce != NULL)
+          || (ce != NULL && next_ce == NULL)
+          || (ce != NULL && next_ce != NULL && ce->cfsi_m != next_ce->cfsi_m)
+          || from > to) {
+         if (ce == NULL) {
+            VG_(printf)("[%#lx .. %#lx]: no CFI info\n", ce_from, from-1);
+         } else {
+            di = ce->di;
+            ML_(ppDiCfSI)(di->cfsi_exprs,
+                          ce_from, from - ce_from,
+                          ce->cfsi_m);
+         }
+         ce = next_ce;
+         ce_from = from;
+      }
+   }
+}
+
 
 /* The main function for DWARF2/3 CFI-based stack unwinding.  Given a
    set of registers in UREGS, modify it to hold the register values
index 926a13f717d1aeaf07d515433332cdec232fa033..89afca60d5fdfd1ce298349e30f64373fa16ee16 100644 (file)
@@ -142,8 +142,12 @@ void ML_(ppDiCfSI) ( const XArray* /* of CfiExpr */ exprs,
          }                                       \
       } while (0)
 
-   VG_(printf)("[%#lx .. %#lx]: ", base,
-                                   base + (UWord)len - 1);
+   if (base != 0 || len != 0)
+      VG_(printf)("[%#lx .. %#lx]: ", base,
+                                      base + (UWord)len - 1);
+   else
+      VG_(printf)("[]: ");
+
    switch (si_m->cfa_how) {
       case CFIC_IA_SPREL: 
          VG_(printf)("let cfa=oldSP+%d", si_m->cfa_off); 
index 6361c5acac1591e99c824036157e8a8c8336591f..7a67fd029d6f10b39b8ba208cd4b3e2ded7ab884 100644 (file)
@@ -248,6 +248,7 @@ int handle_gdb_valgrind_command (char *mon, OutputSink *sink_wanted_at_return)
 "  v.info exectxt          : show stacktraces and stats of all execontexts\n"
 "  v.info scheduler        : show valgrind thread state and stacktrace\n"
 "  v.info stats            : show various valgrind and tool stats\n"
+"  v.info unwind <addr> [<len>] : show unwind debug info for <addr> .. <addr+len>\n"
 "  v.set debuglog <level>  : set valgrind debug log level to <level>\n"
 "  v.set hostvisibility [yes*|no] : (en/dis)ables access by gdb/gdbserver to\n"
 "    Valgrind internal host status/memory\n"
@@ -364,7 +365,7 @@ int handle_gdb_valgrind_command (char *mon, OutputSink *sink_wanted_at_return)
       wcmd = strtok_r (NULL, " ", &ssaveptr);
       switch (kwdid = VG_(keyword_id) 
               ("all_errors n_errs_found last_error gdbserver_status memory"
-               " scheduler stats open_fds exectxt location",
+               " scheduler stats open_fds exectxt location unwind",
                wcmd, kwd_report_all)) {
       case -2:
       case -1: 
@@ -456,6 +457,17 @@ int handle_gdb_valgrind_command (char *mon, OutputSink *sink_wanted_at_return)
          ret = 1;
          break;
       }
+      case 10: { /* unwind */
+         Addr address;
+         SizeT sz = 0;
+         if (VG_(strtok_get_address_and_size) (&address, 
+                                               &sz, &ssaveptr)) {
+            VG_(ppUnwindInfo) (address, address + sz - 1);
+         }
+         ret = 1;
+         break;
+      }
+
       default:
          vg_assert(0);
       }
index 98029ab79eaa7c75fc74cd85f418d7c379a477f8..bb57b33007ec84d24818a036418139e082f33a9d 100644 (file)
@@ -165,6 +165,10 @@ extern Bool VG_(use_FPO_info) ( /*MOD*/Addr* ipP,
                                 Addr min_accessible,
                                 Addr max_accessible );
 
+/* Print the unwind info (if there is some) for the given address
+   range [from,to]. */
+extern void VG_(ppUnwindInfo) (Addr from, Addr to);
+
 /* AVMAs for a symbol. Usually only the lowest address of the entity.
    On ppc64 platforms, also contains tocptr and local_ep.
    These fields should only be accessed using the macros
index 409cddf692546c6b62b76f5df8b4fd973914b521..b767825c5b0d8218204156cbafb94c1e682b4e33 100644 (file)
@@ -1478,6 +1478,14 @@ problems or bugs.</para>
     </para>
   </listitem>
 
+  <listitem>
+    <para><varname>v.info unwind  &lt;addr&gt; [&lt;len&gt;]</varname> shows
+    the CFI unwind debug info for the address range [addr, addr+len-1].
+    The default value of &lt;len&gt; is 1, giving the unwind information
+    for the instruction at &lt;addr&gt;.
+    </para>
+  </listitem>
+
   <listitem>
     <para><varname>v.set debuglog &lt;intvalue&gt;</varname> sets the
     Valgrind debug log level to &lt;intvalue&gt;.  This allows to
index d3c61a1c86d634ffb5ec38516aa17e273f75fffa..c2d2c8d07d1413fa7af4ed9c3929e3417ea468f8 100644 (file)
@@ -65,6 +65,7 @@ debugging valgrind internals monitor commands:
   v.info exectxt          : show stacktraces and stats of all execontexts
   v.info scheduler        : show valgrind thread state and stacktrace
   v.info stats            : show various valgrind and tool stats
+  v.info unwind <addr> [<len>] : show unwind debug info for <addr> .. <addr+len>
   v.set debuglog <level>  : set valgrind debug log level to <level>
   v.set hostvisibility [yes*|no] : (en/dis)ables access by gdb/gdbserver to
     Valgrind internal host status/memory