Skip to content

Instantly share code, notes, and snippets.

@stepancheg
Created October 3, 2012 14:23
Show Gist options
  • Save stepancheg/3827187 to your computer and use it in GitHub Desktop.
Save stepancheg/3827187 to your computer and use it in GitHub Desktop.
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#include <signal.h>
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
void
ccc(void)
{
printf("generating SEGV\n");
*((int *)NULL) = 12;
}
void
bbb(void)
{
ccc();
}
void
aaa(void)
{
bbb();
}
void
show_backtrace(ucontext_t* context)
{
unw_cursor_t cursor;
unw_word_t ip, sp;
int r = unw_init_local(&cursor, context);
if (r < 0) {
printf("unw_init_local failed\n");
abort();
}
for (;;) {
r = unw_step(&cursor);
if (r == 0) {
break;
}
if (r < 0) {
printf("unw_step failed\n");
abort();
}
unw_get_reg(&cursor, UNW_REG_IP, &ip);
unw_get_reg(&cursor, UNW_REG_SP, &sp);
printf("ip = %lx, sp = %lx\n", (long)ip, (long)sp);
Dl_info dli;
memset(&dli, 0, sizeof dli);
if (dladdr((void*) ip, &dli) && dli.dli_sname) {
printf("%s\n", dli.dli_sname);
}
}
abort();
}
void
my_handler(int sig, siginfo_t* ignore, ucontext_t* context)
{
show_backtrace(context);
}
int
main(int argc, char *argv[])
{
struct sigaction sa;
sa.sa_sigaction = &my_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV, &sa, NULL);
aaa();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment