diff options
| -rw-r--r-- | SConstruct | 3 | ||||
| -rw-r--r-- | platform/linuxbsd/crash_handler_linuxbsd.cpp | 40 | 
2 files changed, 25 insertions, 18 deletions
diff --git a/SConstruct b/SConstruct index 1eb6c0adc8..705ef43b3d 100644 --- a/SConstruct +++ b/SConstruct @@ -540,6 +540,9 @@ if selected_platform in platform_list:              env.Append(CCFLAGS=["/Od"])      else:          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:                  env.Append(CCFLAGS=["-g3"])              else: diff --git a/platform/linuxbsd/crash_handler_linuxbsd.cpp b/platform/linuxbsd/crash_handler_linuxbsd.cpp index add69c436f..8d03e3d31c 100644 --- a/platform/linuxbsd/crash_handler_linuxbsd.cpp +++ b/platform/linuxbsd/crash_handler_linuxbsd.cpp @@ -44,6 +44,7 @@  #include <cxxabi.h>  #include <dlfcn.h>  #include <execinfo.h> +#include <link.h>  #include <signal.h>  #include <stdlib.h> @@ -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<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++) {  			char fname[1024];  			Dl_info info; @@ -102,24 +123,7 @@ static void handle_crash(int sig) {  				}  			} -			List<String> 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, &output, &ret); -			if (err == OK) { -				output = output.substr(0, output.length() - 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);  |