Skip to content

Instantly share code, notes, and snippets.

@awreece
Created August 15, 2014 04:28
Show Gist options
  • Save awreece/64c6c06f9da54fe63993 to your computer and use it in GitHub Desktop.
Save awreece/64c6c06f9da54fe63993 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#define MAX_FUNC_NAME 128
static void print_frame(unw_cursor_t *cursor) {
unw_word_t ip, offset, rdi, rsi, rdx;
char func_name[MAX_FUNC_NAME];
int got_func_name =
!unw_get_proc_name(cursor, func_name, sizeof (func_name), &offset);
int got_ip = !unw_get_reg(cursor, UNW_REG_IP, &ip);
int got_rdi = !unw_get_reg(cursor, UNW_X86_64_RDI, &rdi);
int got_rsi = !unw_get_reg(cursor, UNW_X86_64_RSI, &rsi);
int got_rdx = !unw_get_reg(cursor, UNW_X86_64_RDX, &rdx);
if (got_func_name) {
fprintf(stderr, "%s+%#llx", func_name, offset);
} else if (got_ip) {
fprintf(stderr, "%#llx", ip);
} else {
fprintf(stderr, "???");
}
if (got_rdi) fprintf(stderr, " rdi=%#llx", rdi);
if (got_rsi) fprintf(stderr, " rsi=%#llx", rsi);
if (got_rdx) fprintf(stderr, " rdx=%#llx", rdx);
fprintf(stderr, "\n");
}
void print_backtrace(size_t skip) {
unw_context_t uc;
unw_cursor_t cursor;
unw_getcontext(&uc);
unw_init_local(&cursor, &uc);
size_t i = 0;
fprintf(stderr, "\n");
while (unw_step(&cursor) > 0) {
if (i < skip) {
i++;
} else {
print_frame(&cursor);
}
}
}
void exit_backtrace() {
print_backtrace(1);
exit(1);
}
void signal_backtrace(int signum) {
fprintf(stderr, "%s\n", strsignal(signum));
print_backtrace(2);
signal(signum, SIG_DFL);
kill(getpid(), signum);
}
void bar(int y) {
print_backtrace(0);
}
void foo(int x) {
bar(2);
}
int main() {
foo(1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment