Skip to content

Instantly share code, notes, and snippets.

@jsimmons
Created August 28, 2019 15:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsimmons/828dba1ed153b50c00208fc8b7a981c3 to your computer and use it in GitHub Desktop.
Save jsimmons/828dba1ed153b50c00208fc8b7a981c3 to your computer and use it in GitHub Desktop.
#include <elfutils/libdwfl.h>
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
int
main(int argc, const char **argv) {
hoke_main();
}
bool
hoke_term_colour_enabled(int fd) {
return isatty(fd) == 0;
}
void
hoke_report_stacktrace(int skip) {
char *debuginfo_path = NULL;
const Dwfl_Callbacks callbacks = {
.find_debuginfo = dwfl_standard_find_debuginfo,
.find_elf = dwfl_linux_proc_find_elf,
.debuginfo_path = &debuginfo_path,
};
Dwfl *dwfl;
void *frames[48];
int n, n_ptrs;
dwfl = dwfl_begin(&callbacks);
if (dwfl_linux_proc_report(dwfl, getpid()))
goto done;
dwfl_report_end(dwfl, NULL, NULL);
n_ptrs = backtrace(frames, 48);
if (n_ptrs < 1)
goto done;
fprintf(stderr, "\n");
for (n = skip + 1; n < n_ptrs; n++) {
GElf_Addr addr = (uintptr_t) frames[n];
GElf_Sym sym;
GElf_Word shndx;
Dwfl_Module *module = dwfl_addrmodule(dwfl, addr);
Dwfl_Line *line;
const char *name, *modname;
if (!module) {
fprintf(stderr, "#%-2u ?? [%#" PRIx64 "]\n", n, addr);
continue;
}
name = dwfl_module_addrsym(module, addr, &sym, &shndx);
if (!name) {
modname = dwfl_module_info(module, NULL, NULL, NULL,
NULL, NULL, NULL, NULL);
fprintf(stderr, "#%-2u ?? (%s) [%p]\n",
n, modname, addr);
continue;
}
line = dwfl_getsrc(dwfl, addr - sym.st_value);
if (line) {
int lineno;
const char *src = dwfl_lineinfo(line, &addr, &lineno,
NULL, NULL, NULL);
if (src) {
fprintf(stderr, "#%-2u %s+%p (%s:%d) [%p]\n",
n, name, addr - sym.st_value,
src, lineno, addr);
continue;
}
}
modname = dwfl_module_info(module, NULL, NULL, NULL,
NULL, NULL, NULL, NULL);
fprintf(stderr, "#%-2u %s+%p (%s) [%p]\n",
n, name, addr - sym.st_value,
modname, addr);
if(strcmp(name, "main") == 0) {
break;
}
}
fprintf(stderr, "\n");
done:
dwfl_end(dwfl);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment