|
|
@@ -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);
|