Bug 854810 - Use shared-libraries-*.cc instead of home-grown equivalents, r=bgirard
authorJulian Seward <jseward@acm.org>
Wed, 27 Mar 2013 16:09:56 +0100
changeset 126410 b5c4adef15233364bb606708e2fbf2a1e6c40104
parent 126409 9c5b80c5a7f5ae38ee2e956c3d555a8a53e2e6d6
child 126411 4b80fc3424651d3c5f4a55e0db058aac7e87bcbb
push id24482
push userryanvm@gmail.com
push dateWed, 27 Mar 2013 21:03:24 +0000
treeherdermozilla-central@279078670022 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgirard
bugs854810
milestone22.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 854810 - Use shared-libraries-*.cc instead of home-grown equivalents, r=bgirard
tools/profiler/UnwinderThread2.cpp
--- a/tools/profiler/UnwinderThread2.cpp
+++ b/tools/profiler/UnwinderThread2.cpp
@@ -38,20 +38,17 @@
   // mmap
 # include <sys/mman.h>
 #endif
 
 #if defined(SPS_OS_android)
 # include "android-signal-defs.h"
 #endif
 
-#if defined(SPS_OS_darwin)
-# include <mach-o/dyld.h>
-#endif
-
+#include "shared-libraries.h"
 
 /* Verbosity of this module, for debugging:
      0  silent
      1  adds info about debuginfo load success/failure
      2  adds slow-summary stats for buffer fills/misses (RECOMMENDED)
      3  adds per-sample summary lines
      4  adds per-sample frame listing
    Note that level 3 and above produces risk of deadlock, and 
@@ -1253,17 +1250,16 @@ static void* unwind_thr_fn(void* exit_no
 
 #include "google_breakpad/common/minidump_format.h"
 #include "google_breakpad/processor/call_stack.h"
 #include "google_breakpad/processor/stack_frame_cpu.h"
 #include "local_debug_info_symbolizer.h"
 #include "processor/stackwalker_amd64.h"
 #include "processor/stackwalker_arm.h"
 #include "processor/stackwalker_x86.h"
-#include "processor/logging.h"
 #include "common/linux/dump_symbols.h"
 
 #include "google_breakpad/processor/memory_region.h"
 #include "google_breakpad/processor/code_modules.h"
 
 google_breakpad::MemoryRegion* foo = NULL;
 
 using std::string;
@@ -1373,130 +1369,42 @@ public:
   // Creates a new copy of this CodeModule object, which the caller takes
   // ownership of.  The new CodeModule may be of a different concrete class
   // than the CodeModule being copied, but will behave identically to the
   // copied CodeModule as far as the CodeModule interface is concerned.
   const CodeModule* Copy() const { MOZ_CRASH(); return NULL; }
 
  private:
   // record info for a file backed executable mapping
-  // snarfed from /proc/self/maps
   u_int64_t x_start_;
   u_int64_t x_len_;    // may not be zero
   string    filename_; // of the mapped file
 };
 
 
 /* Find out, in a platform-dependent way, where the code modules got
    mapped in the process' virtual address space, and add them to
    |mods_|. */
 static void read_procmaps(std::vector<MyCodeModule*>& mods_)
 {
   MOZ_ASSERT(mods_.size() == 0);
-
-#if defined(SPS_OS_linux) || defined(SPS_OS_android)
-  // read /proc/self/maps and create a vector of CodeModule*
-  FILE* f = fopen("/proc/self/maps", "r");
-  MOZ_ASSERT(f);
-  while (!feof(f)) {
-    unsigned long long int start = 0;
-    unsigned long long int end   = 0;
-    char rr = ' ', ww = ' ', xx = ' ', pp = ' ';
-    unsigned long long int offset = 0, inode = 0;
-    unsigned int devMaj = 0, devMin = 0;
-    int nItems = fscanf(f, "%llx-%llx %c%c%c%c %llx %x:%x %llu",
-                        &start, &end, &rr, &ww, &xx, &pp,
-                        &offset, &devMaj, &devMin, &inode);
-    if (nItems == EOF && feof(f)) break;
-    MOZ_ASSERT(nItems == 10);
-    MOZ_ASSERT(start < end);
-    // read the associated file name, if it is present
-    int ch;
-    // find '/' or EOL
-    while (1) {
-      ch = fgetc(f);
-      MOZ_ASSERT(ch != EOF);
-      if (ch == '\n' || ch == '/') break;
-    }
-    string fname("");
-    if (ch == '/') {
-      fname += (char)ch;
-      while (1) {
-        ch = fgetc(f);
-        MOZ_ASSERT(ch != EOF);
-        if (ch == '\n') break;
-        fname += (char)ch;
-      }
-    }
-    MOZ_ASSERT(ch == '\n');
-    if (0) LOGF("SEG %llx %llx %c %c %c %c %s",
-                start, end, rr, ww, xx, pp, fname.c_str() );
-    if (xx == 'x' && fname != "") {
-      MyCodeModule* cm = new MyCodeModule( start, end-start, fname );
-      mods_.push_back(cm);
-    }
+#if defined(SPS_OS_linux) || defined(SPS_OS_android) || defined(SPS_OS_darwin)
+  SharedLibraryInfo info = SharedLibraryInfo::GetInfoForSelf();
+  for (size_t i = 0; i < info.GetSize(); i++) {
+    const SharedLibrary& lib = info.GetEntry(i);
+    // On Linux, this pulls out two mappings with no names: the VDSO
+    // (understandable but harmless), and the main executable (bad).
+    MyCodeModule* cm 
+      = new MyCodeModule( lib.GetStart(), lib.GetEnd()-lib.GetStart(),
+                          lib.GetName() );
+    mods_.push_back(cm);
   }
-  fclose(f);
-
-#elif defined(SPS_OS_darwin)
-
-# if defined(SPS_PLAT_amd64_darwin)
-  typedef mach_header_64 breakpad_mach_header;
-  typedef segment_command_64 breakpad_mach_segment_command;
-  const int LC_SEGMENT_XX = LC_SEGMENT_64;
-# else // SPS_PLAT_x86_darwin
-  typedef mach_header breakpad_mach_header;
-  typedef segment_command breakpad_mach_segment_command;
-  const int LC_SEGMENT_XX = LC_SEGMENT;
-# endif
-
-  uint32_t n_images = _dyld_image_count();
-  for (uint32_t ix = 0; ix < n_images; ix++) {
-
-    MyCodeModule* cm = NULL;
-    unsigned long slide = _dyld_get_image_vmaddr_slide(ix);
-    const char* name = _dyld_get_image_name(ix);
-    const breakpad_mach_header* header
-      = (breakpad_mach_header*)_dyld_get_image_header(ix);
-    if (!header)
-      continue;
-
-    const struct load_command *cmd =
-      reinterpret_cast<const struct load_command *>(header + 1);
-
-    /* Look through the MachO headers to find out the module's stated
-       VMA, so we can add it to the slide to find its actual VMA.
-       Copied from MinidumpGenerator::WriteModuleStream
-       src/client/mac/handler/minidump_generator.cc. */
-    for (unsigned int i = 0; cmd && (i < header->ncmds); i++) {
-      if (cmd->cmd == LC_SEGMENT_XX) {
-
-        const breakpad_mach_segment_command *seg =
-          reinterpret_cast<const breakpad_mach_segment_command *>(cmd);
-
-        if (!strcmp(seg->segname, "__TEXT")) {
-          cm = new MyCodeModule( seg->vmaddr + slide,
-                                 seg->vmsize, string(name) );
-          break;
-        }
-      }
-      cmd = reinterpret_cast<struct load_command*>((char *)cmd + cmd->cmdsize);
-    }
-    if (cm) {
-      mods_.push_back(cm);
-      if (0) LOGF("SEG %llx %llx %s",
-                  cm->base_address(), cm->base_address() + cm->size(),
-                  cm->code_file().c_str());
-    }
-  }
-
 #else
 # error "Unknown platform"
 #endif
-
   if (0) LOGF("got %d mappings\n", (int)mods_.size());
 }
 
 
 class MyCodeModules : public google_breakpad::CodeModules
 {
  public:
   MyCodeModules() {