]> git.ipfire.org Git - people/ms/gcc.git/commitdiff
libbacktrace: fetch executable path on macOS
authorIan Lance Taylor <iant@golang.org>
Wed, 9 Sep 2020 02:09:21 +0000 (19:09 -0700)
committerIan Lance Taylor <iant@golang.org>
Wed, 9 Sep 2020 02:09:21 +0000 (19:09 -0700)
PR libbacktrace/96973
* fileline.c (macho_get_executable_path): New static function.
(fileline_initialize): Call macho_get_executable_path.

libbacktrace/fileline.c

index cc1011e8b5ddab19e18db94f6a8fce824bb27822..be62b9899c5a7e8a889c781ecbd7e1680f44034d 100644 (file)
@@ -43,6 +43,10 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #include <sys/sysctl.h>
 #endif
 
+#ifdef HAVE_MACH_O_DYLD_H
+#include <mach-o/dyld.h>
+#endif
+
 #include "backtrace.h"
 #include "internal.h"
 
@@ -122,6 +126,35 @@ sysctl_exec_name2 (struct backtrace_state *state,
 
 #endif /* defined (HAVE_KERN_PROC_ARGS) || |defined (HAVE_KERN_PROC) */
 
+#ifdef HAVE_MACH_O_DYLD_H
+
+static char *
+macho_get_executable_path (struct backtrace_state *state,
+                          backtrace_error_callback error_callback, void *data)
+{
+  uint32_t len;
+  char *name;
+
+  len = 0;
+  if (_NSGetExecutablePath (NULL, &len) == 0)
+    return NULL;
+  name = (char *) backtrace_alloc (state, len, error_callback, data);
+  if (name == NULL)
+    return NULL;
+  if (_NSGetExecutablePath (name, &len) != 0)
+    {
+      backtrace_free (state, name, len, error_callback, data);
+      return NULL;
+    }
+  return name;
+}
+
+#else /* !defined (HAVE_MACH_O_DYLD_H) */
+
+#define macho_get_executable_path(state, error_callback, data) NULL
+
+#endif /* !defined (HAVE_MACH_O_DYLD_H) */
+
 /* Initialize the fileline information from the executable.  Returns 1
    on success, 0 on failure.  */
 
@@ -159,7 +192,7 @@ fileline_initialize (struct backtrace_state *state,
 
   descriptor = -1;
   called_error_callback = 0;
-  for (pass = 0; pass < 7; ++pass)
+  for (pass = 0; pass < 8; ++pass)
     {
       int does_not_exist;
 
@@ -188,6 +221,9 @@ fileline_initialize (struct backtrace_state *state,
        case 6:
          filename = sysctl_exec_name2 (state, error_callback, data);
          break;
+       case 7:
+         filename = macho_get_executable_path (state, error_callback, data);
+         break;
        default:
          abort ();
        }