[PATCH] D70628: [Support] Enable file + line info in LLVM stack traces on Darwin.

Lang Hames via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 23 09:17:43 PST 2019


lhames updated this revision to Diff 230761.
lhames added a comment.

- Remove byte-swapping code. This will run in process, so endianness shouldn't


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D70628/new/

https://reviews.llvm.org/D70628

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
@@ -34,6 +34,7 @@
 
 #include "Unix.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/BinaryFormat/MachO.h"
 #include "llvm/Config/config.h"
 #include "llvm/Demangle/Demangle.h"
 #include "llvm/Support/FileSystem.h"
@@ -490,6 +491,75 @@
   dl_iterate_phdr(dl_iterate_phdr_cb, &data);
   return true;
 }
+#elif defined(__APPLE__)
+
+static uintptr_t getImagePreferredLoadAddress(const void *ImageBase) {
+  const char *ImagePtr = reinterpret_cast<const char *>(ImageBase);
+
+  // Process header.
+  const auto *MachHdr = reinterpret_cast<const MachO::mach_header*>(ImagePtr);
+
+  if (MachHdr->magic != MachO::MH_MAGIC && MachHdr->magic != MachO::MH_MAGIC_64)
+    return ~0ULL;
+  bool Is64Bit = MachHdr->magic == MachO::MH_MAGIC_64 ||
+                 MachHdr->magic == MachO::MH_CIGAM_64;
+  ImagePtr += Is64Bit
+    ? sizeof(MachO::mach_header_64)
+    : sizeof(MachO::mach_header);
+
+  // Process load commands.
+  for (uint32_t I = 0; I < MachHdr->ncmds; ++I) {
+    const auto *LC = reinterpret_cast<const MachO::load_command*>(ImagePtr);
+    if (Is64Bit && LC->cmd == MachO::LC_SEGMENT_64) {
+      const auto *LCSeg64 =
+        reinterpret_cast<const MachO::segment_command_64*>(ImagePtr);
+      if (strncmp(LCSeg64->segname, "__TEXT", 16) == 0)
+        return LCSeg64->vmaddr;
+    } else if (!Is64Bit && LC->cmd == MachO::LC_SEGMENT) {
+      const auto *LCSeg = reinterpret_cast<const MachO::segment_command*>(ImagePtr);
+      if (strncmp(LCSeg->segname, "__TEXT", 16) == 0)
+        return LCSeg->vmaddr;
+    }
+
+    ImagePtr += LC->cmdsize;
+
+    // Bail out with an error value if the load command walk takes us out of
+    // bounds. This should never happen with well-formed images.
+    if (ImagePtr - reinterpret_cast<const char *>(ImageBase) >=
+        MachHdr->sizeofcmds)
+      return ~0U;
+  }
+
+  // No segment load command found. Return an error value.
+  return ~0U;
+}
+
+static bool findModulesAndOffsets(void **StackTrace, int Depth,
+                                  const char **Modules, intptr_t *Offsets,
+                                  const char *MainExecutableName,
+                                  StringSaver &StrPool) {
+  for (int I = 0; I != Depth; ++I) {
+    Dl_info dlinfo;
+    dladdr(StackTrace[I], &dlinfo);
+
+    uintptr_t OffsetInImage =
+      (uintptr_t)StackTrace[I] - (uintptr_t)dlinfo.dli_fbase;
+
+    uintptr_t PreferredLoadAddress =
+      getImagePreferredLoadAddress(dlinfo.dli_fbase);
+
+    if (PreferredLoadAddress == (uintptr_t)~0ULL)
+      return false;
+
+    if (auto *basename = strrchr(dlinfo.dli_fname, '/'))
+      Modules[I] = basename + 1;
+    else
+      Modules[I] = dlinfo.dli_fname;
+    Offsets[I] = OffsetInImage + PreferredLoadAddress;
+  }
+  return true;
+}
+
 #else
 /// This platform does not have dl_iterate_phdr, so we do not yet know how to
 /// find all loaded DSOs.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D70628.230761.patch
Type: text/x-patch
Size: 3063 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191123/93b053fe/attachment.bin>


More information about the llvm-commits mailing list