diff options
author | Andy Schwerin <schwerin@mongodb.com> | 2015-12-28 12:48:58 -0500 |
---|---|---|
committer | Ramon Fernandez <ramon@mongodb.com> | 2016-01-11 16:43:51 -0500 |
commit | 421c9d5abd96f3917c591440ab7f9a9e56b486e4 (patch) | |
tree | b2ed807fd8730c60bca8d3dcf7087b137f0fde1a | |
parent | 6fc3b8d0c6a4be82f2b29a222e9eaa2c66f7660f (diff) | |
download | mongo-421c9d5abd96f3917c591440ab7f9a9e56b486e4.tar.gz |
SERVER-21934 Add extra information to OSX stack dumps to support ASLR.
(cherry picked from commit 706d2e0a94c57d5c4a01a4787d78d413f134441e)
-rw-r--r-- | src/mongo/util/stacktrace_posix.cpp | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/src/mongo/util/stacktrace_posix.cpp b/src/mongo/util/stacktrace_posix.cpp index 75a78d32082..230621a6103 100644 --- a/src/mongo/util/stacktrace_posix.cpp +++ b/src/mongo/util/stacktrace_posix.cpp @@ -451,6 +451,15 @@ uint32_t lcType(const char* lcCurr) { return cmd->cmd; } +template <typename SegmentCommandType> +bool maybeAppendLoadAddr(BSONObjBuilder* soInfo, const SegmentCommandType* segmentCommand) { + if (StringData(SEG_TEXT) != segmentCommand->segname) { + return false; + } + *soInfo << "vmaddr" << integerToHex(segmentCommand->vmaddr); + return true; +} + void addOSComponentsToSoMap(BSONObjBuilder* soMap) { const uint32_t numImages = _dyld_image_count(); BSONArrayBuilder soList(soMap->subarrayStart("somap")); @@ -475,16 +484,34 @@ void addOSComponentsToSoMap(BSONObjBuilder* soMap) { const char* const loadCommandsBegin = reinterpret_cast<const char*>(header) + headerSize; const char* const loadCommandsEnd = loadCommandsBegin + header->sizeofcmds; - // Search the "load command" data in the Mach object for the entry - // encoding the UUID of the object. + // Search the "load command" data in the Mach object for the entry encoding the UUID of the + // object, and for the __TEXT segment. Adding the "vmaddr" field of the __TEXT segment load + // command of an executable or dylib to an offset in that library provides an address + // suitable to passing to atos or llvm-symbolizer for symbolization. + // + // See, for example, http://lldb.llvm.org/symbolication.html. + bool foundTextSegment = false; for (const char* lcCurr = loadCommandsBegin; lcCurr < loadCommandsEnd; lcCurr = lcNext(lcCurr)) { - if (LC_UUID != lcType(lcCurr)) - continue; - - const uuid_command* uuidCmd = reinterpret_cast<const uuid_command*>(lcCurr); - soInfo << "buildId" << toHex(uuidCmd->uuid, 16); - break; + switch (lcType(lcCurr)) { + case LC_UUID: { + const auto uuidCmd = reinterpret_cast<const uuid_command*>(lcCurr); + soInfo << "buildId" << toHex(uuidCmd->uuid, 16); + break; + } + case LC_SEGMENT_64: + if (!foundTextSegment) { + foundTextSegment = maybeAppendLoadAddr( + &soInfo, reinterpret_cast<const segment_command_64*>(lcCurr)); + } + break; + case LC_SEGMENT: + if (!foundTextSegment) { + foundTextSegment = maybeAppendLoadAddr( + &soInfo, reinterpret_cast<const segment_command*>(lcCurr)); + } + break; + } } } } |