[PATCH] D142282: [Support] Implement findModulesAndOffsets on Apple 64-bit platforms

Luís Marques via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 21 07:11:59 PST 2023


luismarques created this revision.
Herald added subscribers: hiraditya, krytarowski.
Herald added a project: All.
luismarques requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

To have file name and line information in stack traces (per stack frame) it's necessary to implement `findModulesAndOffsets`.

With this implementation, stack traces can show source location information on macOS (64-bit, for now). To make it work I used the cmake option `LLVM_EXTERNALIZE_DEBUGINFO=True` to generate the `.dSYM` directories and changed the calls to `llvm-symbolizer` to pass `--dsym-hint` arguments with the generated `.dSYM` directories (see follow-up patch). Tested on macOS 13.1.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D142282

Files:
  llvm/lib/Support/Unix/Signals.inc


Index: llvm/lib/Support/Unix/Signals.inc
===================================================================
--- llvm/lib/Support/Unix/Signals.inc
+++ llvm/lib/Support/Unix/Signals.inc
@@ -62,6 +62,9 @@
 #if HAVE_MACH_MACH_H
 #include <mach/mach.h>
 #endif
+#ifdef __APPLE__
+#include <mach-o/dyld.h>
+#endif
 #if HAVE_LINK_H
 #include <link.h>
 #endif
@@ -463,9 +466,9 @@
   RegisterHandlers();
 }
 
-#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && HAVE_LINK_H &&             \
-    (defined(__linux__) || defined(__FreeBSD__) ||                             \
-     defined(__FreeBSD_kernel__) || defined(__NetBSD__))
+#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
+#if HAVE_LINK_H && (defined(__linux__) || defined(__FreeBSD__) ||              \
+    defined(__FreeBSD_kernel__) || defined(__NetBSD__))
 struct DlIteratePhdrData {
   void **StackTrace;
   int depth;
@@ -509,16 +512,50 @@
   dl_iterate_phdr(dl_iterate_phdr_cb, &data);
   return true;
 }
+#elif defined(__APPLE__) && defined(__LP64__)
+static bool findModulesAndOffsets(void **StackTrace, int Depth,
+                                  const char **Modules, intptr_t *Offsets,
+                                  const char *MainExecutableName,
+                                  StringSaver &StrPool) {
+  uint32_t num_imgs = _dyld_image_count();
+  for (uint32_t image_index = 0; image_index < num_imgs; image_index++) {
+    const char *name = _dyld_get_image_name(image_index);
+    intptr_t slide = _dyld_get_image_vmaddr_slide(image_index);
+    auto *header =
+        (const struct mach_header_64 *)_dyld_get_image_header(image_index);
+    if (header == NULL)
+      continue;
+    auto cmd = (const struct load_command *)(&header[1]);
+    for (uint32_t cmd_num = 0; cmd_num < header->ncmds; ++cmd_num) {
+      uint32_t base_cmd = cmd->cmd & ~LC_REQ_DYLD;
+      if (base_cmd == LC_SEGMENT_64) {
+        auto cmd_seg64 = (const struct segment_command_64 *)cmd;
+        for (int j = 0; j < Depth; j++) {
+          if (Modules[j])
+            continue;
+          intptr_t addr = (intptr_t)StackTrace[j];
+          if ((intptr_t)cmd_seg64->vmaddr + slide <= addr &&
+              addr < intptr_t(cmd_seg64->vmaddr + cmd_seg64->vmsize + slide)) {
+            Modules[j] = name;
+            Offsets[j] = addr - slide;
+          }
+        }
+      }
+      cmd = (const load_command *)(((const char *)cmd) + (cmd->cmdsize));
+    }
+  }
+  return true;
+}
 #else
-/// This platform does not have dl_iterate_phdr, so we do not yet know how to
-/// find all loaded DSOs.
+/// We don't yet know how to find all loaded DSOs on this platform.
 static bool findModulesAndOffsets(void **StackTrace, int Depth,
                                   const char **Modules, intptr_t *Offsets,
                                   const char *MainExecutableName,
                                   StringSaver &StrPool) {
   return false;
 }
-#endif // defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && ...
+#endif // per-platform findModulesAndOffsets implementations
+#endif // defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
 
 #if ENABLE_BACKTRACES && defined(HAVE__UNWIND_BACKTRACE)
 static int unwindBacktrace(void **StackTrace, int MaxEntries) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D142282.491072.patch
Type: text/x-patch
Size: 3221 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230121/71c9f133/attachment.bin>


More information about the llvm-commits mailing list