summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Schwerin <schwerin@mongodb.com>2015-12-28 12:48:58 -0500
committerRamon Fernandez <ramon@mongodb.com>2016-01-11 16:43:51 -0500
commit421c9d5abd96f3917c591440ab7f9a9e56b486e4 (patch)
treeb2ed807fd8730c60bca8d3dcf7087b137f0fde1a
parent6fc3b8d0c6a4be82f2b29a222e9eaa2c66f7660f (diff)
downloadmongo-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.cpp43
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;
+ }
}
}
}