functions.c: backtraceHandler(): use libunwind and libelf-utils to provide stacktrace with source code line numbers
This commit is contained in:
parent
88887423f4
commit
10dbcdb8b2
@ -4,6 +4,8 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
pkg_check_modules(RPM REQUIRED rpm)
|
||||
pkg_check_modules(SQLITE3 REQUIRED sqlite3)
|
||||
pkg_check_modules(LIBUNWIND REQUIRED libunwind)
|
||||
pkg_check_modules(LIBDW REQUIRED libdw)
|
||||
find_library(LIBIBERTY NAMES iberty)
|
||||
|
||||
include_directories(include)
|
||||
@ -42,9 +44,11 @@ target_link_libraries(distromatic
|
||||
${RPM_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
${SQLITE3_LIBRARIES}
|
||||
${LIBUNWIND_LIBRARIES}
|
||||
${LIBDW_LIBRARIES}
|
||||
${LIBIBERTY}
|
||||
)
|
||||
target_include_directories(distromatic PUBLIC ${RPM_INCLUDE_DIRS})
|
||||
target_include_directories(distromatic PUBLIC ${RPM_INCLUDE_DIRS} ${LIBUNWIND_INCLUDE_DIRS})
|
||||
#
|
||||
# NOTE: -fno-toplevel-reorder required to prevent Sqlite3 weird problems
|
||||
#
|
||||
@ -64,9 +68,11 @@ target_link_libraries(distroquery
|
||||
${RPM_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
${SQLITE3_LIBRARIES}
|
||||
${LIBUNWIND_LIBRARIES}
|
||||
${LIBDW_LIBRARIES}
|
||||
${LIBIBERTY}
|
||||
)
|
||||
target_include_directories(distroquery PUBLIC ${RPM_INCLUDE_DIRS})
|
||||
target_include_directories(distroquery PUBLIC ${RPM_INCLUDE_DIRS} ${LIBUNWIND_INCLUDE_DIRS})
|
||||
|
||||
install(
|
||||
TARGETS distromatic
|
||||
|
@ -113,7 +113,7 @@ int handleObsoletedPackages(struct configTag *ct, int arch);
|
||||
|
||||
static const char *copyright[] = {
|
||||
PACKAGE_NAME " version " PACKAGE_VERSION,
|
||||
"Copyright (C) 2004-2020 by Silvan Calarco <silvan.calarco@mambasoft.it>",
|
||||
"Copyright (C) 2004-2021 by Silvan Calarco <silvan.calarco@mambasoft.it>",
|
||||
"Copyright (C) 2006 by Davide Madrisan <davide.madrisan@gmail.com>",
|
||||
(char *)0
|
||||
};
|
||||
@ -162,7 +162,7 @@ static const char *helpmsg[] = {
|
||||
" -v, --version display version and exit",
|
||||
"",
|
||||
"Examples:",
|
||||
" distromatic -t devel --genhtml --deps-table",
|
||||
" distromatic -t devel --genhtml --gendatatables",
|
||||
" distromatic -t stable/2.0 --changelogsince 010106",
|
||||
"",
|
||||
"Please report bugs to <"PACKAGE_BUGREPORT">.",
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* distromatic - tool for RPM based repositories
|
||||
*
|
||||
* Copyright (C) 2004-2020 by Silvan Calarco <silvan.calarco@mambasoft.it>
|
||||
* Copyright (C) 2004-2021 by Silvan Calarco <silvan.calarco@mambasoft.it>
|
||||
* Copyright (C) 2006 by Davide Madrisan <davide.madrisan@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
@ -67,29 +67,81 @@
|
||||
#include "functions.h"
|
||||
#include "changelog.h"
|
||||
|
||||
#include <execinfo.h>
|
||||
#define UNW_LOCAL_ONLY
|
||||
#include <elfutils/libdwfl.h>
|
||||
#include <libunwind.h>
|
||||
#include <assert.h>
|
||||
|
||||
static int debug_log = 0;
|
||||
static struct configDefaults configdefaults;
|
||||
static struct configTag *firstconfigtag = NULL;
|
||||
|
||||
/* Obtain a backtrace and print it to stdout. */
|
||||
static void debugInfo(FILE *out, const void* ip)
|
||||
{
|
||||
char *debuginfo_path=NULL;
|
||||
|
||||
Dwfl_Callbacks callbacks={
|
||||
.find_elf=dwfl_linux_proc_find_elf,
|
||||
.find_debuginfo=dwfl_standard_find_debuginfo,
|
||||
.debuginfo_path=&debuginfo_path,
|
||||
};
|
||||
|
||||
Dwfl* dwfl=dwfl_begin(&callbacks);
|
||||
assert(dwfl!=NULL);
|
||||
|
||||
assert(dwfl_linux_proc_report (dwfl, getpid())==0);
|
||||
assert(dwfl_report_end (dwfl, NULL, NULL)==0);
|
||||
|
||||
Dwarf_Addr addr = (uintptr_t)ip;
|
||||
|
||||
Dwfl_Module* module=dwfl_addrmodule (dwfl, addr);
|
||||
|
||||
const char* function_name = dwfl_module_addrname(module, addr);
|
||||
|
||||
fprintf(out, "%s(",function_name);
|
||||
|
||||
Dwfl_Line *line=dwfl_getsrc (dwfl, addr);
|
||||
if(line!=NULL)
|
||||
{
|
||||
int nline;
|
||||
Dwarf_Addr addr;
|
||||
const char* filename=dwfl_lineinfo (line, &addr,&nline,NULL,NULL,NULL);
|
||||
fprintf(out, "%s:%d",strrchr(filename,'/')+1,nline);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *module_name = dwfl_module_info(module,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
fprintf(out, "in %s", module_name);
|
||||
}
|
||||
}
|
||||
|
||||
void backtraceHandler(int sig)
|
||||
{
|
||||
void *array[10];
|
||||
size_t size;
|
||||
char **strings;
|
||||
size_t i;
|
||||
unw_context_t uc;
|
||||
unw_getcontext(&uc);
|
||||
|
||||
size = backtrace (array, 10);
|
||||
strings = (char**)backtrace_symbols (array, size);
|
||||
unw_cursor_t cursor;
|
||||
unw_init_local(&cursor, &uc);
|
||||
|
||||
fprintf(stderr, "Obtained %zd stack frames.\n", size);
|
||||
fprintf(stderr, "*** Received signal %d; stack trace: ***\n", sig);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
fprintf(stderr, "%s\n", strings[i]);
|
||||
while(unw_step(&cursor)>0) {
|
||||
unw_word_t ip;
|
||||
unw_get_reg(&cursor, UNW_REG_IP, &ip);
|
||||
|
||||
free (strings);
|
||||
unw_word_t offset;
|
||||
char name[32];
|
||||
assert(unw_get_proc_name(&cursor, name,sizeof(name), &offset)==0);
|
||||
|
||||
fprintf(stderr, "\tat ");
|
||||
debugInfo(stderr, (void*)(ip-4));
|
||||
fprintf(stderr, ")\n");
|
||||
|
||||
if(strcmp(name,"main")==0)
|
||||
break;
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user