[PATCH] D144839: Add support to symbolize backtraces on crashes on Macho platforms
Mehdi AMINI via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 26 20:25:24 PST 2023
mehdi_amini created this revision.
mehdi_amini added a reviewer: aprantl.
Herald added a subscriber: hiraditya.
Herald added a reviewer: JDevlieghere.
Herald added a project: All.
mehdi_amini requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
llvm-symbolizer still requires to run dsymutil to find debug info though,
I'm not sure if we can teach llvm-symbolizer to find these without?
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D144839
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
@@ -61,6 +61,7 @@
#endif
#if HAVE_MACH_MACH_H
#include <mach/mach.h>
+#include <mach-o/dyld.h>
#endif
#if HAVE_LINK_H
#include <link.h>
@@ -507,6 +508,70 @@
dl_iterate_phdr(dl_iterate_phdr_cb, &data);
return true;
}
+#elif HAVE_MACH_MACH_H
+
+// Use the _dyld_* functions to find the loaded modules and populate
+// the modules and offset arrays for each stack frame.
+static bool findModulesAndOffsets(void **StackTrace, int Depth,
+ const char **Modules, intptr_t *Offsets,
+ const char *MainExecutableName,
+ StringSaver &Unused) {
+ int ImageCount = _dyld_image_count();
+ // Find the image name and the offset for a given PC.
+ auto ProcessPC = [&](intptr_t pc, const char **Name, intptr_t *Offset) {
+ *Name = nullptr;
+ *Offset = 0;
+ // Scan the images in the binary and find the one that contains the PC.
+ for (int ImageID = 0; ImageID < ImageCount; ++ImageID) {
+ // Get the image header, and find the pointer to the first command (right
+ // after the header).
+ const struct mach_header *Header =
+ (const struct mach_header *)_dyld_get_image_header(ImageID);
+ intptr_t ImageOffset = _dyld_get_image_vmaddr_slide(ImageID);
+ intptr_t HeaderSize = sizeof(mach_header);
+ if (Header->magic == MH_MAGIC_64)
+ HeaderSize = sizeof(mach_header_64);
+ const struct load_command *cmd =
+ reinterpret_cast<const struct load_command *>(
+ reinterpret_cast<const char *>(Header) + HeaderSize);
+
+ // Iterate all the load commands, looking for a segment containing the PC.
+ for (unsigned CmdID = 0; CmdID < Header->ncmds;
+ ++CmdID, cmd = (const struct load_command
+ *)(reinterpret_cast<const char *>(cmd) +
+ cmd->cmdsize)) {
+ // Compute the interval of addresses covered by this segment.
+ intptr_t SegStart = 0;
+ intptr_t SegEnd = 0;
+ if (cmd->cmd == LC_SEGMENT) {
+ const struct segment_command *seg =
+ (const struct segment_command *)cmd;
+ SegStart = seg->vmaddr + ImageOffset;
+ SegEnd = SegStart + seg->vmsize;
+ } else if (cmd->cmd == LC_SEGMENT_64) {
+ const struct segment_command_64 *seg =
+ (const struct segment_command_64 *)cmd;
+ SegStart = seg->vmaddr + ImageOffset;
+ SegEnd = SegStart + seg->vmsize;
+ } else {
+ continue;
+ }
+ if ((pc >= SegStart) && (pc < SegEnd)) {
+ *Name = _dyld_get_image_name(ImageID);
+ *Offset = pc - ImageOffset;
+ return;
+ }
+ }
+ }
+ };
+ // Iterate over the stack trace and find the module and offset for each PC.
+ for (int i = 0; i < Depth; i++) {
+ intptr_t pc = reinterpret_cast<intptr_t>(StackTrace[i]);
+ ProcessPC(pc, &Modules[i], &Offsets[i]);
+ }
+ 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: D144839.500654.patch
Type: text/x-patch
Size: 3315 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230227/3e3abfc4/attachment.bin>
More information about the llvm-commits
mailing list