# 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
} \
} 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);
" 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"
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:
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);
}
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
</para>
</listitem>
+ <listitem>
+ <para><varname>v.info unwind <addr> [<len>]</varname> shows
+ the CFI unwind debug info for the address range [addr, addr+len-1].
+ The default value of <len> is 1, giving the unwind information
+ for the instruction at <addr>.
+ </para>
+ </listitem>
+
<listitem>
<para><varname>v.set debuglog <intvalue></varname> sets the
Valgrind debug log level to <intvalue>. This allows to
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