Skip to content

Instantly share code, notes, and snippets.

@nasitra
Created October 9, 2016 06:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nasitra/266c02276ed2d81b37c418a63b8ef491 to your computer and use it in GitHub Desktop.
Save nasitra/266c02276ed2d81b37c418a63b8ef491 to your computer and use it in GitHub Desktop.
Print call stack by using libunwind
#include <libunwind.h>
#include <libunwind-ptrace.h>
#include "backtrace.h"
#define MAX_BACKTRACE_FRAMES 64
void unwind(pid_t pid) {
unw_addr_space_t addr_space = NULL;
struct UPT_info* upt_info = NULL;
unw_cursor_t cursor;
int ret;
size_t num_frames = 0;
addr_space = unw_create_addr_space(&_UPT_accessors, 0);
if (!addr_space) {
printf("unw_create_addr_space failed.");
goto done;
}
upt_info = (struct UPT_info*) _UPT_create(pid);
if (!upt_info) {
printf("Failed to create upt info.");
goto done;
}
ret = unw_init_remote(&cursor, addr_space, upt_info);
if (ret < 0) {
printf("unw_init_remote failed %d", ret);
goto done;
}
do {
unw_word_t pc, sp;
unw_word_t off = 0;
char buf[512];
ret = unw_get_reg(&cursor, UNW_REG_IP, &pc);
if (ret < 0) {
printf("Failed to read IP %d", ret);
break;
}
ret = unw_get_reg(&cursor, UNW_REG_SP, &sp);
if (ret < 0) {
printf("Failed to read SP %d", ret);
break;
}
if (unw_get_proc_name_by_ip(addr_space, pc, buf, sizeof(buf), &off, upt_info) >= 0
&& buf[0] != '\0') {
printf("%p <%s + 0x%lx>\n", (void*) pc, buf, off);
}
num_frames++;
ret = unw_step(&cursor);
} while (ret > 0 && num_frames < MAX_BACKTRACE_FRAMES);
done:
if (upt_info) {
_UPT_destroy(upt_info);
}
if (addr_space) {
unw_destroy_addr_space(addr_space);
}
}
#ifndef BACKTRACE_H_
#define BACKTRACE_H_
#include <sys/types.h>
void unwind(pid_t pid);
#endif /* BACKTRACE_H_ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment