Commit 42da95d9 authored by Aaron Plattner's avatar Aaron Plattner
Browse files

os: print registers in the libunwind version of xorg_backtrace()



If the stack walker finds a signal frame, record the cursor at that point and
then use unw_get_reg() to query the values of the architecture-specific
registers at the frame that triggered the signal.

Example output:

 (EE) Backtrace:
 (EE) 0: hw/xfree86/Xorg (OsSigHandler+0x25) [0x561458bb8195]
 (EE) 1: <signal handler called>
 (EE) 2: hw/xfree86/Xorg (dix_main+0x9c) [0x561458aead6c]
 (EE) 3: /usr/lib/libc.so.6 (__libc_start_main+0xd5) [0x7f2d23170b25]
 (EE) 4: hw/xfree86/Xorg (_start+0x2e) [0x561458aad8be]
 (EE)
 (EE) Registers at frame #2:
 (EE)   rax: 0x0
 (EE)   rbx: 0x561458c3ae60
 (EE)   rcx: 0x7f2d23328943
 (EE)   rdx: 0x0
 (EE)   rsi: 0x7ffcb6025030
 (EE)   rdi: 0xe
 (EE)   rbp: 0x0
 (EE)   rsp: 0x7ffcb6026430
 (EE)    r8: 0x0
 (EE)    r9: 0x0
 (EE)   r10: 0x8
 (EE)   r11: 0x246
 (EE)   r12: 0x561458aad890
 (EE)   r13: 0x0
 (EE)   r14: 0x0
 (EE)   r15: 0x0
 (EE)
 (EE) Segmentation fault at address 0x0
Signed-off-by: Aaron Plattner's avatarAaron Plattner <aplattner@nvidia.com>
parent f13dd7fd
Pipeline #328075 passed with stages
in 17 minutes and 39 seconds
......@@ -40,15 +40,73 @@
#endif
#include <dlfcn.h>
static void
print_registers(int frame, unw_cursor_t cursor)
{
const struct {
const char *name;
int regnum;
} regs[] = {
#if UNW_TARGET_X86_64
{ "rax", UNW_X86_64_RAX },
{ "rbx", UNW_X86_64_RBX },
{ "rcx", UNW_X86_64_RCX },
{ "rdx", UNW_X86_64_RDX },
{ "rsi", UNW_X86_64_RSI },
{ "rdi", UNW_X86_64_RDI },
{ "rbp", UNW_X86_64_RBP },
{ "rsp", UNW_X86_64_RSP },
{ " r8", UNW_X86_64_R8 },
{ " r9", UNW_X86_64_R9 },
{ "r10", UNW_X86_64_R10 },
{ "r11", UNW_X86_64_R11 },
{ "r12", UNW_X86_64_R12 },
{ "r13", UNW_X86_64_R13 },
{ "r14", UNW_X86_64_R14 },
{ "r15", UNW_X86_64_R15 },
#endif
};
const int num_regs = sizeof(regs) / sizeof(*regs);
int ret, i;
if (num_regs == 0)
return;
/*
* Advance the cursor from the signal frame to the one that triggered the
* signal.
*/
frame++;
ret = unw_step(&cursor);
if (unw_step(&cursor) < 0) {
ErrorFSigSafe("unw_step failed: %s [%d]\n", unw_strerror(ret), ret);
return;
}
ErrorFSigSafe("\n");
ErrorFSigSafe("Registers at frame #%d:\n", frame);
for (i = 0; i < num_regs; i++) {
uint64_t val;
ret = unw_get_reg(&cursor, regs[i].regnum, &val);
if (ret < 0) {
ErrorFSigSafe("unw_get_reg(%s) failed: %s [%d]\n",
regs[i].name, unw_strerror(ret), ret);
} else {
ErrorFSigSafe(" %s: 0x%" PRIx64 "\n", regs[i].name, val);
}
}
}
void
xorg_backtrace(void)
{
unw_cursor_t cursor;
unw_cursor_t cursor, signal_cursor;
unw_context_t context;
unw_word_t ip;
unw_word_t off;
unw_proc_info_t pip;
int ret, i = 0;
int ret, i = 0, signal_frame = -1;
char procname[256];
const char *filename;
Dl_info dlinfo;
......@@ -99,6 +157,9 @@ xorg_backtrace(void)
if (unw_is_signal_frame(&cursor)) {
signal_cursor = cursor;
signal_frame = i;
ErrorFSigSafe("%u: <signal handler called>\n", i++);
} else {
ErrorFSigSafe("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,
......@@ -110,6 +171,10 @@ xorg_backtrace(void)
if (ret < 0)
ErrorFSigSafe("unw_step failed: %s [%d]\n", unw_strerror(ret), ret);
}
if (signal_frame >= 0)
print_registers(signal_frame, signal_cursor);
ErrorFSigSafe("\n");
}
#else /* HAVE_LIBUNWIND */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment