aboutsummaryrefslogtreecommitdiff
path: root/third_party/backtrace-mingw/backtrace.c
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2021-11-07 22:51:07 -0500
committerGravatar Chris Xiong <chirs241097@gmail.com> 2021-11-07 22:51:07 -0500
commitf41f3f96657644b12a32d2211110dea1b60aa1f0 (patch)
treeb055ebfaa444d073252c2f5f9d7836e7d0509fb8 /third_party/backtrace-mingw/backtrace.c
parenta42be43a3aa5e1494267f3ae93d70a37afe48673 (diff)
downloadQMidiPlayer-f41f3f96657644b12a32d2211110dea1b60aa1f0.tar.xz
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.
Diffstat (limited to 'third_party/backtrace-mingw/backtrace.c')
-rw-r--r--third_party/backtrace-mingw/backtrace.c62
1 files changed, 35 insertions, 27 deletions
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;
}