Daniele Bartolini 2 лет назад
Родитель
Сommit
3677555938
1 измененных файлов с 23 добавлено и 12 удалено
  1. 23 12
      src/core/error/callstack_linux.cpp

+ 23 - 12
src/core/error/callstack_linux.cpp

@@ -6,30 +6,41 @@
 #include "core/platform.h"
 
 #if CROWN_PLATFORM_LINUX && (CROWN_COMPILER_GCC || CROWN_COMPILER_CLANG)
+#include "core/process.h"
 #include "core/strings/string.inl"
 #include "core/strings/string_stream.inl"
 #include <cxxabi.h>
 #include <execinfo.h>
-#include <stdlib.h>
+#include <stdlib.h> // free
 #include <string.h> // strchr
 #include <unistd.h> // getpid
-#include <stdio.h>  // popen
 #include <stb_sprintf.h>
 
 namespace crown
 {
 namespace error
 {
-	static const char *addr2line(const char *addr, char *line, int len)
+	static const char *addr2line(char *line, int len, const char *addr)
 	{
-		char buf[256];
-		stbsp_snprintf(buf, sizeof(buf), "addr2line -s -e /proc/%u/exe %s", getpid(), addr);
-		FILE *f = popen(buf, "r");
-		if (f) {
-			char *ret = fgets(line, len, f);
-			CE_UNUSED(ret);
-			line[strlen32(line) - 1] = '\0';
-			pclose(f);
+		char process_exe[256];
+		stbsp_snprintf(process_exe, sizeof(process_exe), "/proc/%u/exe", getpid());
+
+		const char *argv[] =
+		{
+			"addr2line",
+			"-s",
+			"-e",
+			process_exe,
+			addr,
+			NULL
+		};
+
+		Process pr;
+		if (pr.spawn(argv, CROWN_PROCESS_STDOUT_PIPE | CROWN_PROCESS_STDERR_MERGE) == 0) {
+			u32 num_read;
+			pr.read(&num_read, line, len);
+			line[num_read - 1] = '\0';
+			pr.wait();
 			return line;
 		}
 		return "<addr2line missing>";
@@ -72,7 +83,7 @@ namespace error
 					, msg
 					, (demangle_ok == 0 ? real_name : mangled_name)
 					, offset_begin
-					, addr2line(addr_begin, line, sizeof(line))
+					, addr2line(line, sizeof(line), addr_begin)
 					);
 
 				free(real_name);