diff --git a/platform/server/detect.py b/platform/server/detect.py index da654ae49..cf6a95eb3 100644 --- a/platform/server/detect.py +++ b/platform/server/detect.py @@ -51,7 +51,6 @@ def get_flags(): def configure(env): - ## Build type if env["target"] == "release": @@ -76,6 +75,11 @@ def configure(env): env.Prepend(CCFLAGS=["-g3"]) env.Append(LINKFLAGS=["-rdynamic"]) + 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"]) + ## Architecture is64 = sys.maxsize > 2 ** 32 diff --git a/platform/x11/crash_handler_x11.cpp b/platform/x11/crash_handler_x11.cpp index e2d35ea4b..03a1b2260 100644 --- a/platform/x11/crash_handler_x11.cpp +++ b/platform/x11/crash_handler_x11.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -79,7 +80,27 @@ static void handle_crash(int sig) { } print_error(vformat("Dumping the backtrace. %s", msg)); 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) { + List 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, true, nullptr, &output, &ret); + Vector addr2line_results; + if (err == OK) { + addr2line_results = output.substr(0, output.length() - 1).split("\n", false); + } + for (size_t i = 1; i < size; i++) { char fname[1024]; Dl_info info; @@ -102,24 +123,7 @@ static void handle_crash(int sig) { } } - List args; - - 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, true, nullptr, &output, &ret); - if (err == OK) { - output.erase(output.length() - 1, 1); - } - - print_error(vformat("[%d] %s (%s)", (int64_t)i, fname, output)); + print_error(vformat("[%d] %s (%s)", (int64_t)i, fname, err == OK ? addr2line_results[i] : "")); } free(strings); diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 92f430155..6a37e2662 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -111,6 +111,11 @@ def configure(env): env.Prepend(CCFLAGS=["-g3"]) env.Append(LINKFLAGS=["-rdynamic"]) + 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"]) + ## Architecture is64 = sys.maxsize > 2**32