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 idunknown
push userunknown
push dateunknown
reviewerscjones, blocking-fennec
bugs605832
milestone2.0b8pre
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__ */