# HG changeset patch # User Ted Mielczarek # Date 1290042003 18000 # Node ID 56ee92febe98f4b38f5f22b361ec63cb0721ee87 # Parent 3f7113eda8fccf859760ef3f512ae9344872022b bug 605832 - Remote AddLibraryMapping from the child process, and use the results for child process minidump generation. r=cjones diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -46,6 +46,7 @@ #endif #include "ContentChild.h" +#include "CrashReporterChild.h" #include "TabChild.h" #include "AudioChild.h" @@ -55,6 +56,7 @@ #include "mozilla/jsipc/PContextWrapperChild.h" #include "mozilla/dom/ExternalHelperAppChild.h" #include "mozilla/dom/StorageChild.h" +#include "mozilla/dom/PCrashReporterChild.h" #include "nsAudioStream.h" @@ -96,6 +98,10 @@ static const int kRelativeNiceness = 10; #include "nsAccelerometer.h" +#if defined(ANDROID) +#include "APKOpen.h" +#endif + using namespace mozilla::ipc; using namespace mozilla::net; using namespace mozilla::places; @@ -239,6 +245,21 @@ ContentChild::Init(MessageLoop* aIOLoop, Open(aChannel, aParentHandle, aIOLoop); sSingleton = this; +#if defined(ANDROID) + PCrashReporterChild* crashreporter = SendPCrashReporterConstructor(); + InfallibleTArray 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; } @@ -271,6 +292,19 @@ ContentChild::DeallocPBrowser(PBrowserCh return true; } +PCrashReporterChild* +ContentChild::AllocPCrashReporter() +{ + return new CrashReporterChild(); +} + +bool +ContentChild::DeallocPCrashReporter(PCrashReporterChild* crashreporter) +{ + delete crashreporter; + return true; +} + PTestShellChild* ContentChild::AllocPTestShell() { diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -80,6 +80,9 @@ public: 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*); diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -40,6 +40,7 @@ #include "ContentParent.h" #include "TabParent.h" +#include "CrashReporterParent.h" #include "History.h" #include "mozilla/ipc/TestShellParent.h" #include "mozilla/net/NeckoParent.h" @@ -391,6 +392,19 @@ ContentParent::DeallocPBrowser(PBrowserP return true; } +PCrashReporterParent* +ContentParent::AllocPCrashReporter() +{ + return new CrashReporterParent(); +} + +bool +ContentParent::DeallocPCrashReporter(PCrashReporterParent* crashreporter) +{ + delete crashreporter; + return true; +} + PTestShellParent* ContentParent::AllocPTestShell() { diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -116,6 +116,9 @@ private: 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); diff --git a/dom/ipc/CrashReporterChild.h b/dom/ipc/CrashReporterChild.h 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 + * + * 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 diff --git a/dom/ipc/CrashReporterParent.cpp b/dom/ipc/CrashReporterParent.cpp 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 + * + * 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& 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 diff --git a/dom/ipc/CrashReporterParent.h b/dom/ipc/CrashReporterParent.h 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 + * + * 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& m); +}; +} // namespace dom +} // namespace mozilla diff --git a/dom/ipc/Makefile.in b/dom/ipc/Makefile.in --- a/dom/ipc/Makefile.in +++ b/dom/ipc/Makefile.in @@ -59,6 +59,8 @@ EXPORTS_mozilla/dom = \ ContentChild.h \ ContentParent.h \ ContentProcess.h \ + CrashReporterChild.h \ + CrashReporterParent.h \ TabParent.h \ TabChild.h \ $(NULL) @@ -69,6 +71,7 @@ CPPSRCS = \ ContentProcess.cpp \ ContentParent.cpp \ ContentChild.cpp \ + CrashReporterParent.cpp \ TabParent.cpp \ TabChild.cpp \ TabMessageUtils.cpp \ diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -38,6 +38,7 @@ include protocol PAudio; include protocol PBrowser; +include protocol PCrashReporter; include protocol PTestShell; include protocol PNecko; include protocol PExternalHelperApp; @@ -83,6 +84,7 @@ rpc protocol PContent { manages PAudio; manages PBrowser; + manages PCrashReporter; manages PTestShell; manages PNecko; manages PExternalHelperApp; @@ -104,6 +106,7 @@ child: NotifyAlertsObserver(nsCString topic, nsString data); + GeolocationUpdate(GeoPosition somewhere); // nsIPermissionManager messages @@ -113,7 +116,8 @@ child: parent: PNecko(); - + PCrashReporter(); + PStorage(StorageConstructData data); PAudio(PRInt32 aNumChannels, PRInt32 aRate, PRInt32 aFormat); diff --git a/dom/ipc/PCrashReporter.ipdl b/dom/ipc/PCrashReporter.ipdl 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 + * + * 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 diff --git a/dom/ipc/ipdl.mk b/dom/ipc/ipdl.mk --- a/dom/ipc/ipdl.mk +++ b/dom/ipc/ipdl.mk @@ -39,6 +39,7 @@ IPDLSRCS = \ PBrowser.ipdl \ PContent.ipdl \ PContentDialog.ipdl \ + PCrashReporter.ipdl \ PDocumentRenderer.ipdl \ PContentPermissionRequest.ipdl \ $(NULL) diff --git a/toolkit/crashreporter/nsExceptionHandler.cpp b/toolkit/crashreporter/nsExceptionHandler.cpp --- a/toolkit/crashreporter/nsExceptionHandler.cpp +++ b/toolkit/crashreporter/nsExceptionHandler.cpp @@ -78,6 +78,8 @@ # 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 #include #include @@ -103,6 +105,7 @@ #include "nsInterfaceHashtable.h" #include "prprf.h" #include "nsIXULAppInfo.h" +#include #include #if defined(XP_MACOSX) @@ -255,6 +258,8 @@ typedef struct { size_t file_offset; } mapping_info; static std::vector library_mappings; +typedef std::map MappingMap; +static MappingMap child_library_mappings; void FileIDToGUID(const char* file_id, u_int8_t guid[sizeof(MDGUID)]) { @@ -1619,6 +1624,24 @@ OnChildProcessDumpRequested(void* aConte #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)), @@ -1676,11 +1699,17 @@ OOPInit() 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) @@ -2031,6 +2060,38 @@ void AddLibraryMapping(const char* libra 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 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 diff --git a/toolkit/crashreporter/nsExceptionHandler.h b/toolkit/crashreporter/nsExceptionHandler.h --- a/toolkit/crashreporter/nsExceptionHandler.h +++ b/toolkit/crashreporter/nsExceptionHandler.h @@ -169,6 +169,16 @@ void AddLibraryMapping(const char* libra 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 }