Bug 829621 - Compute the breakpad-id for OS X. r=BenWa.
authorRafael Ávila de Espíndola <respindola@mozilla.org>
Fri, 11 Jan 2013 14:38:40 -0500
changeset 118625 c9ec22f372adf0070a24089f7495eaf3f5ba7a75
parent 118624 97dc4bb4507285145ba0f3aa855a6e83f24e4b18
child 118626 ef384134776b78e33a2f7251effc4a8999379241
push idunknown
push userunknown
push dateunknown
reviewersBenWa
bugs829621
milestone21.0a1
Bug 829621 - Compute the breakpad-id for OS X. r=BenWa.
tools/profiler/shared-libraries-macos.cc
--- a/tools/profiler/shared-libraries-macos.cc
+++ b/tools/profiler/shared-libraries-macos.cc
@@ -8,16 +8,17 @@
 #include <mach-o/dyld_images.h>
 #include <mach/task_info.h>
 #include <mach/task.h>
 #include <mach/mach_init.h>
 #include <mach/mach_traps.h>
 #include <string.h>
 #include <stdlib.h>
 #include <vector>
+#include <sstream>
 
 #include "shared-libraries.h"
 
 #ifndef MAC_OS_X_VERSION_10_6
 #define MAC_OS_X_VERSION_10_6 1060
 #endif
 
 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
@@ -50,35 +51,51 @@ typedef segment_command_64 mach_segment_
 #define seg_size uint64_t
 #endif
 
 static
 void addSharedLibrary(const platform_mach_header* header, char *name, SharedLibraryInfo &info) {
   const struct load_command *cmd =
     reinterpret_cast<const struct load_command *>(header + 1);
 
-  seg_size size;
+  seg_size size = 0;
+  unsigned long long start = reinterpret_cast<unsigned long long>(header);
   // Find the cmd segment in the macho image. It will contain the offset we care about.
-  for (unsigned int i = 0; cmd && (i < header->ncmds); ++i) {
+  const uint8_t *uuid_bytes = nullptr;
+  for (unsigned int i = 0;
+       cmd && (i < header->ncmds) && (uuid_bytes == nullptr || size == 0);
+       ++i) {
     if (cmd->cmd == CMD_SEGMENT) {
       const mach_segment_command_type *seg =
         reinterpret_cast<const mach_segment_command_type *>(cmd);
 
       if (!strcmp(seg->segname, "__TEXT")) {
         size = seg->vmsize;
-        unsigned long long start = reinterpret_cast<unsigned long long>(header);
-        info.AddSharedLibrary(SharedLibrary(start, start+seg->vmsize, 0,
-                                            "", name));
-        return;
       }
+    } else if (cmd->cmd == LC_UUID) {
+      const uuid_command *ucmd = reinterpret_cast<const uuid_command *>(cmd);
+      uuid_bytes = ucmd->uuid;
     }
 
     cmd = reinterpret_cast<const struct load_command *>
       (reinterpret_cast<const char *>(cmd) + cmd->cmdsize);
   }
+
+  std::stringstream uuid;
+  uuid << std::hex << std::uppercase;
+  if (uuid_bytes != nullptr) {
+    for (int i = 0; i < 16; ++i) {
+      uuid << ((uuid_bytes[i] & 0xf0) >> 4);
+      uuid << (uuid_bytes[i] & 0xf);
+    }
+    uuid << '0';
+  }
+
+  info.AddSharedLibrary(SharedLibrary(start, start + size, 0, uuid.str(),
+                                      name));
 }
 
 // Use dyld to inspect the macho image information. We can build the SharedLibraryEntry structure
 // giving us roughtly the same info as /proc/PID/maps in Linux.
 SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf()
 {
   SharedLibraryInfo sharedLibraryInfo;