Alter linux debug stacktraces handling to support more environments

- Use -gdwarf-4 to support both LLVM and GCC when calling addr2line
- Subtract position-independant execuable relocation when passing the
  address to addr2line
This commit is contained in:
Ekaterina Vaartis 2023-01-15 01:18:00 +03:00
parent fcba87e696
commit 5e041eee11
2 changed files with 25 additions and 18 deletions

View File

@ -540,6 +540,9 @@ if selected_platform in platform_list:
env.Append(CCFLAGS=["/Od"]) env.Append(CCFLAGS=["/Od"])
else: else:
if env["debug_symbols"]: if env["debug_symbols"]:
# Adding dwarf-4 explicitly makes stacktraces work with clang builds,
# otherwise addr2line doesn't understand them
env.Append(CCFLAGS=["-gdwarf-4"])
if env.dev_build: if env.dev_build:
env.Append(CCFLAGS=["-g3"]) env.Append(CCFLAGS=["-g3"])
else: else:

View File

@ -44,6 +44,7 @@
#include <cxxabi.h> #include <cxxabi.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <execinfo.h> #include <execinfo.h>
#include <link.h>
#include <signal.h> #include <signal.h>
#include <stdlib.h> #include <stdlib.h>
@ -79,7 +80,27 @@ static void handle_crash(int sig) {
} }
print_error(vformat("Dumping the backtrace. %s", msg)); print_error(vformat("Dumping the backtrace. %s", msg));
char **strings = backtrace_symbols(bt_buffer, size); char **strings = backtrace_symbols(bt_buffer, size);
// PIE executable relocation, zero for non-PIE executables
uintptr_t relocation = _r_debug.r_map->l_addr;
if (strings) { if (strings) {
List<String> args;
for (size_t i = 0; i < size; i++) {
char str[1024];
snprintf(str, 1024, "%p", (void *)((uintptr_t)bt_buffer[i] - relocation));
args.push_back(str);
}
args.push_back("-e");
args.push_back(_execpath);
// Try to get the file/line number using addr2line
int ret;
String output = "";
Error err = OS::get_singleton()->execute(String("addr2line"), args, &output, &ret);
Vector<String> addr2line_results;
if (err == OK) {
addr2line_results = output.substr(0, output.length() - 1).split("\n", false);
}
for (size_t i = 1; i < size; i++) { for (size_t i = 1; i < size; i++) {
char fname[1024]; char fname[1024];
Dl_info info; Dl_info info;
@ -102,24 +123,7 @@ static void handle_crash(int sig) {
} }
} }
List<String> args; print_error(vformat("[%d] %s (%s)", (int64_t)i, fname, err == OK ? addr2line_results[i] : ""));
char str[1024];
snprintf(str, 1024, "%p", bt_buffer[i]);
args.push_back(str);
args.push_back("-e");
args.push_back(_execpath);
String output = "";
// Try to get the file/line number using addr2line
int ret;
Error err = OS::get_singleton()->execute(String("addr2line"), args, &output, &ret);
if (err == OK) {
output = output.substr(0, output.length() - 1);
}
print_error(vformat("[%d] %s (%s)", (int64_t)i, fname, output));
} }
free(strings); free(strings);