Sfoglia il codice sorgente

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
Ekaterina Vaartis 2 anni fa
parent
commit
5e041eee11
2 ha cambiato i file con 25 aggiunte e 18 eliminazioni
  1. 3 0
      SConstruct
  2. 22 18
      platform/linuxbsd/crash_handler_linuxbsd.cpp

+ 3 - 0
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:

+ 22 - 18
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);