diff mbox series

libbacktrace patch committed: Get executable name on macOS

Message ID CAOyqgcXgDBaeP9aiNJcCOb7=H2GgNY59-iK6vgNSq+Vakh-31g@mail.gmail.com
State New
Headers show
Series libbacktrace patch committed: Get executable name on macOS | expand

Commit Message

Ian Lance Taylor Sept. 9, 2020, 2:12 a.m. UTC
This patch to libbacktrace gets the executable name on macOS using
_NSGetExecutablePath.  This is another aspect of PR 96973.  Tested
basic functionality on macOS.  Bootstrapped and ran libbacktrace tests
on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

 * fileline.c (macho_get_executable_path): New static function.
(fileline_initialize): Call macho_get_executable_path.
diff mbox series

Patch

diff --git a/libbacktrace/fileline.c b/libbacktrace/fileline.c
index cc1011e8b5d..be62b9899c5 100644
--- a/libbacktrace/fileline.c
+++ b/libbacktrace/fileline.c
@@ -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 ();
 	}