bug 603592 - Add an API for the Android embedding to use to provide info about shared libraries mapped into anonymous mappings. r=mwu a=blocking-fennec
authorTed Mielczarek <ted.mielczarek@gmail.com>
Tue, 19 Oct 2010 15:05:47 -0400
changeset 56284 781d0b2374705e2863cbf147fa16f7fe75251a35
parent 56283 b799dd554e1259cb519ce2ee7048bf5e23587a01
child 56285 8fc42e3e185f22dbfbb13944f61c19d0f45e74c7
push id16462
push userblassey@mozilla.com
push dateThu, 21 Oct 2010 00:44:42 +0000
treeherdermozilla-central@8fc42e3e185f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmwu, blocking-fennec
bugs603592
milestone2.0b8pre
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 603592 - Add an API for the Android embedding to use to provide info about shared libraries mapped into anonymous mappings. r=mwu a=blocking-fennec
toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.cc
toolkit/crashreporter/nsExceptionHandler.cpp
toolkit/crashreporter/nsExceptionHandler.h
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.cc
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.cc
@@ -432,25 +432,27 @@ class MinidumpWriter {
         dumper_(crashing_pid),
         memory_blocks_(dumper_.allocator()),
         mapping_info_(mappings) {
   }
 
   // case (2) above
   MinidumpWriter(const char* filename,
                  pid_t pid,
-                 pid_t blame_thread)
+                 pid_t blame_thread,
+                 const MappingList& mappings)
       : filename_(filename),
         siginfo_(NULL),         // we fill this in if we find blame_thread
         ucontext_(NULL),
         float_state_(NULL),
         crashing_tid_(blame_thread),
         crashing_tid_pc_(0),    // set if we find blame_thread
         dumper_(pid),
-        memory_blocks_(dumper_.allocator()) {
+        memory_blocks_(dumper_.allocator()),
+        mapping_info_(mappings) {
   }
 
   bool Init() {
     return dumper_.Init() && minidump_writer_.Open(filename_) &&
            dumper_.ThreadsAttach();
   }
 
   ~MinidumpWriter() {
@@ -1374,15 +1376,17 @@ bool WriteMinidump(const char* filename,
   MinidumpWriter writer(filename, crashing_process, context, mappings);
   if (!writer.Init())
     return false;
   return writer.Dump();
 }
 
 bool WriteMinidump(const char* filename, pid_t process,
                    pid_t process_blamed_thread) {
-  MinidumpWriter writer(filename, process, process_blamed_thread);
+  //TODO: support mappings here
+  MappingList m;
+  MinidumpWriter writer(filename, process, process_blamed_thread, m);
   if (!writer.Init())
     return false;
   return writer.Dump();
 }
 
 }  // namespace google_breakpad
--- a/toolkit/crashreporter/nsExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsExceptionHandler.cpp
@@ -98,16 +98,17 @@
 #include "mozilla/Mutex.h"
 #include "nsDebug.h"
 #include "nsCRT.h"
 #include "nsILocalFile.h"
 #include "nsIFileStreams.h"
 #include "nsInterfaceHashtable.h"
 #include "prprf.h"
 #include "nsIXULAppInfo.h"
+#include <vector>
 
 #if defined(XP_MACOSX)
 CFStringRef reporterClientAppID = CFSTR("org.mozilla.crashreporter");
 #endif
 
 #if defined(MOZ_IPC)
 #include "nsIUUIDGenerator.h"
 
@@ -237,16 +238,40 @@ static cpu_type_t pref_cpu_types[2] = {
 #elif defined(__ppc__)
                                  CPU_TYPE_POWERPC,
 #endif
                                  CPU_TYPE_ANY };
 
 static posix_spawnattr_t spawnattr;
 #endif
 
+#if defined(__ANDROID__)
+// Android builds use a custom library loader,
+// so the embedding will provide a list of shared
+// libraries that are mapped into anonymous mappings.
+typedef struct {
+  std::string name;
+  std::string debug_id;
+  uintptr_t   start_address;
+  size_t      length;
+  size_t      file_offset;
+} mapping_info;
+static std::vector<mapping_info> library_mappings;
+
+void FileIDToGUID(const char* file_id, u_int8_t guid[sizeof(MDGUID)])
+{
+  for (int i = 0; i < sizeof(MDGUID); i++) {
+    int c;
+    sscanf(file_id, "%02X", &c);
+    guid[i] = (u_int8_t)(c & 0xFF);
+    file_id += 2;
+  }
+}
+#endif
+
 #ifdef XP_LINUX
 inline void
 my_timetostring(time_t t, char* buffer, size_t buffer_length)
 {
   my_memset(buffer, 0, buffer_length);
   my_itos(buffer, t, my_int_len(t));
 }
 #endif
@@ -678,16 +703,28 @@ nsresult SetExceptionHandler(nsILocalFil
   Boolean keyExistsAndHasValidFormat = false;
   Boolean prefValue = ::CFPreferencesGetAppBooleanValue(CFSTR("OSCrashReporter"),
                                                         kCFPreferencesCurrentApplication,
                                                         &keyExistsAndHasValidFormat);
   if (keyExistsAndHasValidFormat)
     showOSCrashReporter = prefValue;
 #endif
 
+#if defined(__ANDROID__)
+  for (unsigned int i = 0; i < library_mappings.size(); i++) {
+    u_int8_t guid[sizeof(MDGUID)];
+    FileIDToGUID(library_mappings[i].debug_id.c_str(), guid);
+    gExceptionHandler->AddMappingInfo(library_mappings[i].name,
+                                      guid,
+                                      library_mappings[i].start_address,
+                                      library_mappings[i].length,
+                                      library_mappings[i].file_offset);
+  }
+#endif
+
   return NS_OK;
 }
 
 bool GetEnabled()
 {
   return gExceptionHandler != nsnull && !gExceptionHandler->IsOutOfProcess();
 }
 
@@ -1956,9 +1993,37 @@ UnsetRemoteExceptionHandler()
 {
   delete gExceptionHandler;
   gExceptionHandler = NULL;
   return true;
 }
 
 #endif  // MOZ_IPC
 
+#if defined(__ANDROID__)
+void AddLibraryMapping(const char* library_name,
+                       const char* file_id,
+                       uintptr_t   start_address,
+                       size_t      mapping_length,
+                       size_t      file_offset)
+{
+  if (!gExceptionHandler) {
+    mapping_info info;
+    info.name = library_name;
+    info.debug_id = file_id;
+    info.start_address = start_address;
+    info.length = mapping_length;
+    info.file_offset = file_offset;
+    library_mappings.push_back(info);
+  }
+  else {
+    u_int8_t guid[sizeof(MDGUID)];
+    FileIDToGUID(file_id, guid);
+    gExceptionHandler->AddMappingInfo(library_name,
+                                      guid,
+                                      start_address,
+                                      mapping_length,
+                                      file_offset);
+  }
+}
+#endif
+
 } // namespace CrashReporter
--- a/toolkit/crashreporter/nsExceptionHandler.h
+++ b/toolkit/crashreporter/nsExceptionHandler.h
@@ -152,11 +152,24 @@ bool CreateNotificationPipeForChild(int*
 
 // Child-side API
 bool SetRemoteExceptionHandler();
 
 #endif  // XP_WIN32
 
 bool UnsetRemoteExceptionHandler();
 #endif // MOZ_IPC
+
+#if defined(__ANDROID__)
+// Android builds use a custom library loader, so /proc/<pid>/maps
+// will just show anonymous mappings for all the non-system
+// shared libraries. This API is to work around that by providing
+// info about the shared libraries that are mapped into these anonymous
+// mappings.
+void AddLibraryMapping(const char* library_name,
+                       const char* file_id,
+                       uintptr_t   start_address,
+                       size_t      mapping_length,
+                       size_t      file_offset);
+#endif
 }
 
 #endif /* nsExceptionHandler_h__ */