bug 605832 - Remote AddLibraryMapping from the child process, and use the results for child process minidump generation. r=cjones a=blocking-fennec

This commit is contained in:
Ted Mielczarek 2010-11-24 09:15:03 -05:00
parent 83a740b386
commit 99d03e6dc7
13 changed files with 391 additions and 1 deletions

View File

@ -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<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;
}
@ -271,6 +292,19 @@ ContentChild::DeallocPBrowser(PBrowserChild* iframe)
return true;
}
PCrashReporterChild*
ContentChild::AllocPCrashReporter()
{
return new CrashReporterChild();
}
bool
ContentChild::DeallocPCrashReporter(PCrashReporterChild* crashreporter)
{
delete crashreporter;
return true;
}
PTestShellChild*
ContentChild::AllocPTestShell()
{

View File

@ -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*);

View File

@ -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(PBrowserParent* frame)
return true;
}
PCrashReporterParent*
ContentParent::AllocPCrashReporter()
{
return new CrashReporterParent();
}
bool
ContentParent::DeallocPCrashReporter(PCrashReporterParent* crashreporter)
{
delete crashreporter;
return true;
}
PTestShellParent*
ContentParent::AllocPTestShell()
{

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -61,6 +61,8 @@ EXPORTS_mozilla/dom = \
ContentChild.h \
ContentParent.h \
ContentProcess.h \
CrashReporterChild.h \
CrashReporterParent.h \
TabParent.h \
TabChild.h \
$(NULL)
@ -71,6 +73,7 @@ CPPSRCS = \
ContentProcess.cpp \
ContentParent.cpp \
ContentChild.cpp \
CrashReporterParent.cpp \
TabParent.cpp \
TabChild.cpp \
TabMessageUtils.cpp \

View File

@ -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;
@ -113,6 +115,7 @@ child:
parent:
PNecko();
PCrashReporter();
PStorage(StorageConstructData data);

View File

@ -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__();
};
}
}

View File

@ -39,6 +39,7 @@ IPDLSRCS = \
PBrowser.ipdl \
PContent.ipdl \
PContentDialog.ipdl \
PCrashReporter.ipdl \
PDocumentRenderer.ipdl \
PContentPermissionRequest.ipdl \
$(NULL)

View File

@ -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 <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
@ -103,6 +105,7 @@
#include "nsInterfaceHashtable.h"
#include "prprf.h"
#include "nsIXULAppInfo.h"
#include <map>
#include <vector>
#if defined(XP_MACOSX)
@ -255,6 +258,8 @@ typedef struct {
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)])
{
@ -1619,6 +1624,24 @@ OnChildProcessDumpRequested(void* aContext,
#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* library_name,
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

View File

@ -169,6 +169,16 @@ void AddLibraryMapping(const char* library_name,
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
}