bug 605832 - Remote AddLibraryMapping from the child process, and use the results for child process minidump generation. r=cjones a=blocking-fennec
authorTed Mielczarek <ted.mielczarek@gmail.com>
Wed, 24 Nov 2010 09:15:03 -0500
changeset 58170 55b7f3d63b7ae004893a2f696017a675b86a114a
parent 58169 aa662b68d60449a73b2f8f55b92d57d0610ae292
child 58171 871cdedc077be1980aca7c5c1f22c187b89f0192
push id17182
push usertmielczarek@mozilla.com
push dateWed, 24 Nov 2010 16:47:44 +0000
treeherdermozilla-central@55b7f3d63b7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones, blocking-fennec
bugs605832
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 605832 - Remote AddLibraryMapping from the child process, and use the results for child process minidump generation. r=cjones a=blocking-fennec
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/CrashReporterChild.h
dom/ipc/CrashReporterParent.cpp
dom/ipc/CrashReporterParent.h
dom/ipc/Makefile.in
dom/ipc/PContent.ipdl
dom/ipc/PCrashReporter.ipdl
dom/ipc/ipdl.mk
toolkit/crashreporter/nsExceptionHandler.cpp
toolkit/crashreporter/nsExceptionHandler.h
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -41,25 +41,27 @@
 #include <gtk/gtk.h>
 #endif
 
 #ifdef MOZ_WIDGET_QT
 #include "nsQAppInstance.h"
 #endif
 
 #include "ContentChild.h"
+#include "CrashReporterChild.h"
 #include "TabChild.h"
 #include "AudioChild.h"
 
 #include "mozilla/ipc/TestShellChild.h"
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/ipc/XPCShellEnvironment.h"
 #include "mozilla/jsipc/PContextWrapperChild.h"
 #include "mozilla/dom/ExternalHelperAppChild.h"
 #include "mozilla/dom/StorageChild.h"
+#include "mozilla/dom/PCrashReporterChild.h"
 
 #include "nsAudioStream.h"
 
 #include "nsIObserverService.h"
 #include "nsTObserverArray.h"
 #include "nsIObserver.h"
 #include "nsIPrefService.h"
 #include "nsServiceManagerUtils.h"
@@ -91,16 +93,20 @@
 #include <sys/resource.h>
 // TODO: For other platforms that support setpriority, figure out
 //       appropriate values of niceness
 static const int kRelativeNiceness = 10;
 #endif
 
 #include "nsAccelerometer.h"
 
+#if defined(ANDROID)
+#include "APKOpen.h"
+#endif
+
 using namespace mozilla::ipc;
 using namespace mozilla::net;
 using namespace mozilla::places;
 using namespace mozilla::docshell;
 
 namespace mozilla {
 namespace dom {
 class AlertObserver
@@ -234,16 +240,31 @@ ContentChild::Init(MessageLoop* aIOLoop,
     setpriority(PRIO_PROCESS, 0, getpriority(PRIO_PROCESS, 0) +
             (relativeNicenessStr ? atoi(relativeNicenessStr) :
              kRelativeNiceness));
 #endif
 
     Open(aChannel, aParentHandle, aIOLoop);
     sSingleton = this;
 
+#if defined(ANDROID)
+    PCrashReporterChild* crashreporter = SendPCrashReporterConstructor();
+    InfallibleTArray<Mapping> mappings;
+    const struct mapping_info *info = getLibraryMapping();
+    while (info->name) {
+        mappings.AppendElement(Mapping(nsDependentCString(info->name),
+                                       nsDependentCString(info->file_id),
+                                       info->base,
+                                       info->len,
+                                       info->offset));
+        info++;
+    }
+    crashreporter->SendAddLibraryMappings(mappings);
+#endif
+
     return true;
 }
 
 void
 ContentChild::InitXPCOM()
 {
     nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
     if (!svc) {
@@ -266,16 +287,29 @@ ContentChild::AllocPBrowser(const PRUint
 bool
 ContentChild::DeallocPBrowser(PBrowserChild* iframe)
 {
     TabChild* child = static_cast<TabChild*>(iframe);
     NS_RELEASE(child);
     return true;
 }
 
+PCrashReporterChild*
+ContentChild::AllocPCrashReporter()
+{
+    return new CrashReporterChild();
+}
+
+bool
+ContentChild::DeallocPCrashReporter(PCrashReporterChild* crashreporter)
+{
+    delete crashreporter;
+    return true;
+}
+
 PTestShellChild*
 ContentChild::AllocPTestShell()
 {
     return new TestShellChild();
 }
 
 bool
 ContentChild::DeallocPTestShell(PTestShellChild* shell)
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -75,16 +75,19 @@ public:
     }
 
     /* if you remove this, please talk to cjones or dougt */
     virtual bool RecvDummy(Shmem& foo) { return true; }
 
     virtual PBrowserChild* AllocPBrowser(const PRUint32& aChromeFlags);
     virtual bool DeallocPBrowser(PBrowserChild*);
 
+    virtual PCrashReporterChild* AllocPCrashReporter();
+    virtual bool DeallocPCrashReporter(PCrashReporterChild*);
+
     virtual PTestShellChild* AllocPTestShell();
     virtual bool DeallocPTestShell(PTestShellChild*);
     virtual bool RecvPTestShellConstructor(PTestShellChild*);
 
     virtual PAudioChild* AllocPAudio(const PRInt32&,
                                      const PRInt32&,
                                      const PRInt32&);
     virtual bool DeallocPAudio(PAudioChild*);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -35,16 +35,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "ContentParent.h"
 
 #include "TabParent.h"
+#include "CrashReporterParent.h"
 #include "History.h"
 #include "mozilla/ipc/TestShellParent.h"
 #include "mozilla/net/NeckoParent.h"
 #include "nsHashPropertyBag.h"
 #include "nsIFilePicker.h"
 #include "nsIWindowWatcher.h"
 #include "nsIDOMWindow.h"
 #include "nsIPrefBranch.h"
@@ -386,16 +387,29 @@ ContentParent::AllocPBrowser(const PRUin
 bool
 ContentParent::DeallocPBrowser(PBrowserParent* frame)
 {
   TabParent* parent = static_cast<TabParent*>(frame);
   NS_RELEASE(parent);
   return true;
 }
 
+PCrashReporterParent*
+ContentParent::AllocPCrashReporter()
+{
+  return new CrashReporterParent();
+}
+
+bool
+ContentParent::DeallocPCrashReporter(PCrashReporterParent* crashreporter)
+{
+  delete crashreporter;
+  return true;
+}
+
 PTestShellParent*
 ContentParent::AllocPTestShell()
 {
   return new TestShellParent();
 }
 
 bool
 ContentParent::DeallocPTestShell(PTestShellParent* shell)
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -111,16 +111,19 @@ private:
     using PContentParent::SendPTestShellConstructor;
 
     ContentParent();
     virtual ~ContentParent();
 
     virtual PBrowserParent* AllocPBrowser(const PRUint32& aChromeFlags);
     virtual bool DeallocPBrowser(PBrowserParent* frame);
 
+    virtual PCrashReporterParent* AllocPCrashReporter();
+    virtual bool DeallocPCrashReporter(PCrashReporterParent* crashreporter);
+
     virtual PTestShellParent* AllocPTestShell();
     virtual bool DeallocPTestShell(PTestShellParent* shell);
 
     virtual PAudioParent* AllocPAudio(const PRInt32&,
                                      const PRInt32&,
                                      const PRInt32&);
     virtual bool DeallocPAudio(PAudioParent*);
 
new file mode 100644
--- /dev/null
+++ b/dom/ipc/CrashReporterChild.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set sw=4 ts=8 et tw=80 : 
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ted Mielczarek <ted.mielczarek@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#include "mozilla/dom/PCrashReporterChild.h"
+
+namespace mozilla {
+namespace dom {
+class CrashReporterChild :
+    public PCrashReporterChild
+{
+ public:
+    CrashReporterChild() {
+      MOZ_COUNT_CTOR(CrashReporterChild);
+    }
+    virtual ~CrashReporterChild() {
+      MOZ_COUNT_DTOR(CrashReporterChild);
+    }
+};
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/ipc/CrashReporterParent.cpp
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set sw=4 ts=8 et tw=80 : 
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ted Mielczarek <ted.mielczarek@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#include "CrashReporterParent.h"
+#include "nsExceptionHandler.h"
+
+#include "base/process_util.h"
+
+using namespace base;
+
+namespace mozilla {
+namespace dom {
+
+void
+CrashReporterParent::ActorDestroy(ActorDestroyReason why)
+{
+#if defined(__ANDROID__)
+  CrashReporter::RemoveLibraryMappingsForChild(ProcessId(OtherProcess()));
+#endif
+}
+
+bool
+CrashReporterParent::RecvAddLibraryMappings(const InfallibleTArray<Mapping>& mappings)
+{
+#if defined(__ANDROID__)
+  for (PRUint32 i = 0; i < mappings.Length(); i++) {
+    const Mapping& m = mappings[i];
+    CrashReporter::AddLibraryMappingForChild(ProcessId(OtherProcess()),
+                                             m.library_name().get(),
+                                             m.file_id().get(),
+                                             m.start_address(),
+                                             m.mapping_length(),
+                                             m.file_offset());
+  }
+#endif
+  return true;
+}
+
+CrashReporterParent::CrashReporterParent()
+{
+    MOZ_COUNT_CTOR(CrashReporterParent);
+}
+
+CrashReporterParent::~CrashReporterParent()
+{
+    MOZ_COUNT_DTOR(CrashReporterParent);
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/ipc/CrashReporterParent.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set sw=4 ts=8 et tw=80 : 
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ted Mielczarek <ted.mielczarek@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#include "mozilla/dom/PCrashReporterParent.h"
+
+namespace mozilla {
+namespace dom {
+class CrashReporterParent :
+    public PCrashReporterParent
+{
+public:
+    CrashReporterParent();
+    virtual ~CrashReporterParent();
+
+ protected:
+  virtual void ActorDestroy(ActorDestroyReason why);
+
+  virtual bool
+    RecvAddLibraryMappings(const InfallibleTArray<Mapping>& m);
+};
+} // namespace dom
+} // namespace mozilla
--- a/dom/ipc/Makefile.in
+++ b/dom/ipc/Makefile.in
@@ -56,26 +56,29 @@ EXPORTS = TabMessageUtils.h PCOMContentP
 EXPORTS_NAMESPACES = mozilla/dom
 
 EXPORTS_mozilla/dom = \
   AudioChild.h \
   AudioParent.h \
   ContentChild.h \
   ContentParent.h \
   ContentProcess.h \
+  CrashReporterChild.h \
+  CrashReporterParent.h \
   TabParent.h \
   TabChild.h \
   $(NULL)
 
 CPPSRCS = \
   AudioChild.cpp \
   AudioParent.cpp \
   ContentProcess.cpp \
   ContentParent.cpp \
   ContentChild.cpp \
+  CrashReporterParent.cpp \
   TabParent.cpp \
   TabChild.cpp \
   TabMessageUtils.cpp \
   $(NULL)
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -33,16 +33,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 include protocol PAudio;
 include protocol PBrowser;
+include protocol PCrashReporter;
 include protocol PTestShell;
 include protocol PNecko;
 include protocol PExternalHelperApp;
 include protocol PStorage;
 
 include "mozilla/chrome/RegistryMessageUtils.h";
 include "mozilla/net/NeckoMessageUtils.h";
 
@@ -78,16 +79,17 @@ union StorageConstructData
     null_t;
     StorageClone;
 };
 
 rpc protocol PContent
 {
     manages PAudio;
     manages PBrowser;
+    manages PCrashReporter;
     manages PTestShell;
     manages PNecko;
     manages PExternalHelperApp;
     manages PStorage;
 
 child:
     PBrowser(PRUint32 chromeFlags);
 
@@ -108,16 +110,17 @@ child:
 
     // nsIPermissionManager messages
     AddPermission(Permission permission);
 
     AccelerationChanged(double x, double y, double z);
 
 parent:
     PNecko();
+    PCrashReporter();
     
     PStorage(StorageConstructData data);
 
     PAudio(PRInt32 aNumChannels, PRInt32 aRate, PRInt32 aFormat);
 
     // Services remoting
 
     async StartVisitedQuery(URI uri);
new file mode 100644
--- /dev/null
+++ b/dom/ipc/PCrashReporter.ipdl
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set sw=4 ts=8 et tw=80 : 
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ted Mielczarek <ted.mielczarek@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+include protocol PContent;
+
+namespace mozilla {
+namespace dom {
+
+struct Mapping {
+  nsCString library_name;
+  nsCString file_id;
+  uintptr_t start_address;
+  size_t mapping_length;
+  size_t file_offset;
+};
+
+protocol PCrashReporter {
+  manager PContent;
+parent:
+  AddLibraryMappings(Mapping[] m);
+  __delete__();
+};
+
+}
+}
\ No newline at end of file
--- a/dom/ipc/ipdl.mk
+++ b/dom/ipc/ipdl.mk
@@ -34,11 +34,12 @@
 #
 # ***** END LICENSE BLOCK *****
 
 IPDLSRCS = \
   PAudio.ipdl \
   PBrowser.ipdl \
   PContent.ipdl \
   PContentDialog.ipdl \
+  PCrashReporter.ipdl \
   PDocumentRenderer.ipdl \
   PContentPermissionRequest.ipdl \
   $(NULL)
--- a/toolkit/crashreporter/nsExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsExceptionHandler.cpp
@@ -73,16 +73,18 @@
 #include "nsIINIParser.h"
 #include "common/linux/linux_libc_support.h"
 #include "common/linux/linux_syscall_support.h"
 #if defined(MOZ_IPC)
 #  include "client/linux/crash_generation/client_info.h"
 #  include "client/linux/crash_generation/crash_generation_server.h"
 #endif
 #include "client/linux/handler/exception_handler.h"
+#include "client/linux/minidump_writer/linux_dumper.h"
+#include "client/linux/minidump_writer/minidump_writer.h"
 #include <fcntl.h>
 #include <sys/types.h>
 #include <unistd.h>
 #elif defined(XP_SOLARIS)
 #include "client/solaris/handler/exception_handler.h"
 #include <fcntl.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -98,16 +100,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 <map>
 #include <vector>
 
 #if defined(XP_MACOSX)
 CFStringRef reporterClientAppID = CFSTR("org.mozilla.crashreporter");
 #endif
 
 #if defined(MOZ_IPC)
 #include "nsIUUIDGenerator.h"
@@ -250,16 +253,18 @@ static posix_spawnattr_t spawnattr;
 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;
+typedef std::map<PRUint32,google_breakpad::MappingList> MappingMap;
+static MappingMap child_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;
@@ -1614,16 +1619,34 @@ OnChildProcessDumpRequested(void* aConte
   CreateFileFromPath(
 #ifdef XP_MACOSX
                      aFilePath,
 #else
                      *aFilePath,
 #endif
                      getter_AddRefs(minidump));
 
+#if defined(__ANDROID__)
+  // Do dump generation here since the CrashGenerationServer doesn't
+  // have access to the library mappings.
+  MappingMap::const_iterator iter = 
+    child_library_mappings.find(aClientInfo->pid_);
+  if (iter == child_library_mappings.end()) {
+    NS_WARNING("No library mappings found for child, can't write minidump!");
+    return;
+  }
+
+  if (!google_breakpad::WriteMinidump(aFilePath->c_str(),
+                                      aClientInfo->pid_,
+                                      aClientInfo->crash_context,
+                                      aClientInfo->crash_context_size,
+                                      iter->second))
+    return;
+#endif
+
   if (!WriteExtraForMinidump(minidump,
                              Blacklist(kSubprocessBlacklist,
                                        NS_ARRAY_LENGTH(kSubprocessBlacklist)),
                              getter_AddRefs(extraFile)))
     return;
 
   if (ShouldReport())
     MoveToPending(minidump, extraFile);
@@ -1671,21 +1694,27 @@ OOPInit()
     &dumpPath);
 
 #elif defined(XP_LINUX)
   if (!CrashGenerationServer::CreateReportChannel(&serverSocketFd,
                                                   &clientSocketFd))
     NS_RUNTIMEABORT("can't create crash reporter socketpair()");
 
   const std::string dumpPath = gExceptionHandler->dump_path();
+  bool generateDumps = true;
+#if defined(__ANDROID__)
+  // On Android, the callback will do dump generation, since it needs
+  // to pass the library mappings.
+  generateDumps = false;
+#endif
   crashServer = new CrashGenerationServer(
     serverSocketFd,
     OnChildProcessDumpRequested, NULL,
     NULL, NULL,                 // we don't care about process exit here
-    true,                       // automatically generate dumps
+    generateDumps,
     &dumpPath);
 
 #elif defined(XP_MACOSX)
   childCrashNotifyPipe =
     PR_smprintf("gecko-crash-server-pipe.%i",
                 static_cast<int>(getpid()));
   const std::string dumpPath = gExceptionHandler->dump_path();
 
@@ -2026,11 +2055,43 @@ void AddLibraryMapping(const char* libra
     FileIDToGUID(file_id, guid);
     gExceptionHandler->AddMappingInfo(library_name,
                                       guid,
                                       start_address,
                                       mapping_length,
                                       file_offset);
   }
 }
+
+#ifdef MOZ_IPC
+void AddLibraryMappingForChild(PRUint32    childPid,
+                               const char* library_name,
+                               const char* file_id,
+                               uintptr_t   start_address,
+                               size_t      mapping_length,
+                               size_t      file_offset)
+{
+  if (child_library_mappings.find(childPid) == child_library_mappings.end())
+    child_library_mappings[childPid] = google_breakpad::MappingList();
+  google_breakpad::MappingInfo info;
+  info.start_addr = start_address;
+  info.size = mapping_length;
+  info.offset = file_offset;
+  strcpy(info.name, library_name);
+ 
+  std::pair<google_breakpad::MappingInfo, u_int8_t[sizeof(MDGUID)]> mapping;
+  mapping.first = info;
+  u_int8_t guid[sizeof(MDGUID)];
+  FileIDToGUID(file_id, guid);
+  memcpy(mapping.second, guid, sizeof(MDGUID));
+  child_library_mappings[childPid].push_back(mapping);
+}
+
+void RemoveLibraryMappingsForChild(PRUint32 childPid)
+{
+  MappingMap::iterator iter = child_library_mappings.find(childPid);
+  if (iter != child_library_mappings.end())
+    child_library_mappings.erase(iter);
+}
+#endif
 #endif
 
 } // namespace CrashReporter
--- a/toolkit/crashreporter/nsExceptionHandler.h
+++ b/toolkit/crashreporter/nsExceptionHandler.h
@@ -164,12 +164,22 @@ bool UnsetRemoteExceptionHandler();
 // 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);
+
+#if defined(MOZ_IPC)
+void AddLibraryMappingForChild(PRUint32    childPid,
+                               const char* library_name,
+                               const char* file_id,
+                               uintptr_t   start_address,
+                               size_t      mapping_length,
+                               size_t      file_offset);
+void RemoveLibraryMappingsForChild(PRUint32 childPid);
+#endif
 #endif
 }
 
 #endif /* nsExceptionHandler_h__ */