From f41f3f96657644b12a32d2211110dea1b60aa1f0 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Sun, 7 Nov 2021 22:51:07 -0500 Subject: Fixes for backtrace. (How did this thing work in the first place?) Instead of dumping the stack trace into stderr, it is now redirected to backtrace.log in the working directory. Fixed symbol names for amd64. It probably won't work on i386 anymore. --- third_party/backtrace-mingw/CMakeLists.txt | 4 ++ third_party/backtrace-mingw/backtrace.c | 62 +++++++++++++++++------------- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/third_party/backtrace-mingw/CMakeLists.txt b/third_party/backtrace-mingw/CMakeLists.txt index 394d420..1258617 100644 --- a/third_party/backtrace-mingw/CMakeLists.txt +++ b/third_party/backtrace-mingw/CMakeLists.txt @@ -1,11 +1,15 @@ add_library(backtrace SHARED backtrace.c) find_path(BFD_INCLUDE_DIR NAMES bfd.h) +include_directories(${BFD_INCLUDE_DIR}) find_library(BFD_LIBRARIES NAMES bfd) find_library(IBERTY_LIBRARIES NAMES iberty) +find_library(INTL_LIBRARIES NAMES intl) find_package(ZLIB REQUIRED) +set_target_properties(backtrace PROPERTIES PREFIX "") target_link_libraries(backtrace ${BFD_LIBRARIES} ${IBERTY_LIBRARIES} + ${INTL_LIBRARIES} ${ZLIB_LIBRARIES} imagehlp ) diff --git a/third_party/backtrace-mingw/backtrace.c b/third_party/backtrace-mingw/backtrace.c index b9ddcf4..cd5a255 100644 --- a/third_party/backtrace-mingw/backtrace.c +++ b/third_party/backtrace-mingw/backtrace.c @@ -61,6 +61,7 @@ struct bfd_set { struct find_info { asymbol **symbol; bfd_vma counter; + bfd_vma base_addr; const char *file; const char *func; unsigned line; @@ -138,7 +139,7 @@ output_print(struct output_buffer *ob, const char * format, ...) ob->buf[ob->ptr] = '\0'; va_list ap; va_start(ap,format); - vsnprintf(ob->buf + ob->ptr , ob->sz - ob->ptr , format, ap); + vsnprintf(ob->buf + ob->ptr, ob->sz - ob->ptr, format, ap); va_end(ap); ob->ptr = strlen(ob->buf + ob->ptr) + ob->ptr; @@ -152,23 +153,27 @@ lookup_section(bfd *abfd, asection *sec, void *opaque_data) if (data->func) return; - if (!(bfd_get_section_flags(abfd, sec) & SEC_ALLOC)) + if (!(bfd_section_flags(sec) & SEC_ALLOC)) return; - bfd_vma vma = bfd_get_section_vma(abfd, sec); - if (data->counter < vma || vma + bfd_get_section_size(sec) <= data->counter) - return; + bfd_vma vma = bfd_section_vma(sec); + bfd_vma addr = data->counter; + if (addr < vma || addr >= vma + bfd_section_size(sec)) + addr -= data->base_addr; //relocated? + if (addr < vma || addr >= vma + bfd_section_size(sec)) + return; - bfd_find_nearest_line(abfd, sec, data->symbol, data->counter - vma, &(data->file), &(data->func), &(data->line)); + bfd_find_nearest_line(abfd, sec, data->symbol, addr - vma, &(data->file), &(data->func), &(data->line)); } static void -find(struct bfd_ctx * b, DWORD offset, const char **file, const char **func, unsigned *line) +find_sym(struct bfd_ctx * b, DWORD64 offset, DWORD64 base, const char **file, const char **func, unsigned *line) { struct find_info data; data.func = NULL; data.symbol = b->symbol; data.counter = offset; + data.base_addr = base; data.file = NULL; data.func = NULL; data.line = 0; @@ -242,10 +247,10 @@ close_bfd_ctx(struct bfd_ctx *bc) } static struct bfd_ctx * -get_bc(struct bfd_set *set , const char *procname, int *err) +get_bc(struct bfd_set *set, const char *procname, int *err) { while(set->name) { - if (strcmp(set->name , procname) == 0) { + if (strcmp(set->name, procname) == 0) { return set->bc; } set = set->next; @@ -277,15 +282,12 @@ release_set(struct bfd_set *set) static void _backtrace(struct output_buffer *ob, struct bfd_set *set, int depth , LPCONTEXT context) { - char procname[MAX_PATH]; - GetModuleFileNameA(NULL, procname, sizeof procname); - struct bfd_ctx *bc = NULL; int err = BFD_ERR_OK; DWORD machine_type = 0; - STACKFRAME frame; - memset(&frame,0,sizeof(frame)); + STACKFRAME64 frame; + memset(&frame, 0, sizeof(frame)); #if defined(_M_IX86) || defined(__i386__) machine_type = IMAGE_FILE_MACHINE_I386; @@ -317,8 +319,8 @@ _backtrace(struct output_buffer *ob, struct bfd_set *set, int depth , LPCONTEXT &frame, context, 0, - SymFunctionTableAccess, - SymGetModuleBase, 0)) { + SymFunctionTableAccess64, + SymGetModuleBase64, 0)) { --depth; if (depth < 0) @@ -328,7 +330,7 @@ _backtrace(struct output_buffer *ob, struct bfd_set *set, int depth , LPCONTEXT symbol->SizeOfStruct = (sizeof *symbol) + 255; symbol->MaxNameLength = 254; - DWORD module_base = SymGetModuleBase(process, frame.AddrPC.Offset); + DWORD64 module_base = SymGetModuleBase64(process, frame.AddrPC.Offset); const char * module_name = "[unknown module]"; if (module_base && @@ -337,17 +339,21 @@ _backtrace(struct output_buffer *ob, struct bfd_set *set, int depth , LPCONTEXT bc = get_bc(set, module_name, &err); } + PLOADED_IMAGE exeimg = ImageLoad(module_name, NULL); + DWORD64 imbase = exeimg->FileHeader->OptionalHeader.ImageBase; + ImageUnload(exeimg); + const char * source_file = NULL; const char * func = NULL; unsigned line = 0; if (bc) { - find(bc,frame.AddrPC.Offset,&source_file,&func,&line); + find_sym(bc, frame.AddrPC.Offset, module_base - imbase, &source_file, &func, &line); } if (source_file == NULL) { - DWORD dummy = 0; - if (SymGetSymFromAddr(process, frame.AddrPC.Offset, &dummy, symbol)) { + DWORD64 dummy = 0; + if (SymGetSymFromAddr64(process, frame.AddrPC.Offset, &dummy, symbol)) { source_file = symbol->Name; } else { @@ -355,14 +361,14 @@ _backtrace(struct output_buffer *ob, struct bfd_set *set, int depth , LPCONTEXT } } if (func == NULL) { - output_print(ob,"0x%08x from %s in %s %s \n", + output_print(ob, "0x%08llx from %s in %s %s \n", frame.AddrPC.Offset, module_name, source_file, bfd_errors[err]); } else { - output_print(ob,"0x%08x in %s at %s:%d from %s \n", + output_print(ob, "0x%08llx in %s at %s:%d from %s \n", frame.AddrPC.Offset, func, source_file, @@ -387,7 +393,7 @@ exception_filter(LPEXCEPTION_POINTERS info) else { bfd_init(); PEXCEPTION_RECORD rec = info->ExceptionRecord; - output_print(&ob,"Unhandled exception occured at 0x%08x: %s.\n", + output_print(&ob,"Unhandled exception occured at 0x%08llx: %s.\n", rec->ExceptionAddress, exception_name(rec->ExceptionCode) ); @@ -399,14 +405,16 @@ exception_filter(LPEXCEPTION_POINTERS info) output_print(&ob, "The data at memory address 0x%08x could not be %s.\n", rec->ExceptionInformation[1], op); } - struct bfd_set *set = calloc(1,sizeof(*set)); - _backtrace(&ob , set , 128 , info->ContextRecord); + struct bfd_set *set = calloc(1, sizeof(*set)); + _backtrace(&ob, set, 128, info->ContextRecord); release_set(set); SymCleanup(GetCurrentProcess()); } - fputs(g_output , stderr); + FILE *btf = fopen("backtrace.log", "w"); + fputs(g_output, btf); + fclose(btf); return EXCEPTION_CONTINUE_SEARCH; } @@ -436,7 +444,7 @@ __printf__(const char * format, ...) { int value; va_list arg; va_start(arg, format); - value = vprintf ( format, arg ); + value = vprintf(format, arg); va_end(arg); return value; } -- cgit v1.2.3