зеркало из https://github.com/mozilla/gecko-dev.git
Switch PPluginModule from PCrashReporter to shmem-based CrashReportHost/Client. (bug 1338281 part 5, r=billm)
This commit is contained in:
Родитель
0c95d36053
Коммит
3a24634204
|
@ -24,11 +24,6 @@ CrashReporterChild::GetCrashReporter()
|
|||
reporters = &child->ManagedPCrashReporterChild();
|
||||
break;
|
||||
}
|
||||
case GeckoProcessType_Plugin: {
|
||||
PluginModuleChild* child = PluginModuleChild::GetChrome();
|
||||
reporters = &child->ManagedPCrashReporterChild();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -40,34 +40,6 @@ public:
|
|||
bool
|
||||
GenerateCrashReport(Toplevel* t, const AnnotationTable* processNotes);
|
||||
|
||||
/*
|
||||
* Attempt to generate a parent/child pair of minidumps from the given
|
||||
* toplevel actor. This calls CrashReporter::CreateMinidumpsAndPair to
|
||||
* generate the minidumps. Crash reporter annotations set prior to this
|
||||
* call will be saved via PairedDumpCallbackExtra into an .extra file
|
||||
* under the proper crash id. AnnotateCrashReport annotations are not
|
||||
* set in this call and the report is not finalized.
|
||||
*
|
||||
* @returns true if successful, false otherwise.
|
||||
*/
|
||||
template<class Toplevel>
|
||||
bool
|
||||
GeneratePairedMinidump(Toplevel* t);
|
||||
|
||||
/*
|
||||
* Attempts to take a minidump of the current process and pair that with
|
||||
* a named minidump handed in by the caller.
|
||||
*
|
||||
* @param aTopLevel - top level actor this reporter is associated with.
|
||||
* @param aMinidump - the minidump to associate with.
|
||||
* @param aPairName - the name of the additional minidump.
|
||||
* @returns true if successful, false otherwise.
|
||||
*/
|
||||
template<class Toplevel>
|
||||
bool
|
||||
GenerateMinidumpAndPair(Toplevel* aTopLevel, nsIFile* aMinidump,
|
||||
const nsACString& aPairName);
|
||||
|
||||
/**
|
||||
* Apply child process annotations to an existing paired mindump generated
|
||||
* with GeneratePairedMinidump.
|
||||
|
@ -115,15 +87,6 @@ public:
|
|||
bool
|
||||
GenerateCrashReportForMinidump(nsIFile* minidump,
|
||||
const AnnotationTable* processNotes);
|
||||
|
||||
/*
|
||||
* Instantiate a new crash reporter actor from a given parent that manages
|
||||
* the protocol.
|
||||
*
|
||||
* @returns true if successful, false otherwise.
|
||||
*/
|
||||
template<class Toplevel>
|
||||
static bool CreateCrashReporter(Toplevel* actor);
|
||||
#endif // MOZ_CRASHREPORTER
|
||||
|
||||
/*
|
||||
|
@ -179,59 +142,6 @@ public:
|
|||
};
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
template<class Toplevel>
|
||||
inline bool
|
||||
CrashReporterParent::GeneratePairedMinidump(Toplevel* t)
|
||||
{
|
||||
mozilla::ipc::ScopedProcessHandle child;
|
||||
#ifdef XP_MACOSX
|
||||
child = t->Process()->GetChildTask();
|
||||
#else
|
||||
if (!base::OpenPrivilegedProcessHandle(t->OtherPid(), &child.rwget())) {
|
||||
NS_WARNING("Failed to open child process handle.");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
nsCOMPtr<nsIFile> childDump;
|
||||
if (CrashReporter::CreateMinidumpsAndPair(child,
|
||||
mMainThread,
|
||||
NS_LITERAL_CSTRING("browser"),
|
||||
nullptr, // pair with a dump of this process and thread
|
||||
getter_AddRefs(childDump)) &&
|
||||
CrashReporter::GetIDFromMinidump(childDump, mChildDumpID)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class Toplevel>
|
||||
inline bool
|
||||
CrashReporterParent::GenerateMinidumpAndPair(Toplevel* aTopLevel,
|
||||
nsIFile* aMinidumpToPair,
|
||||
const nsACString& aPairName)
|
||||
{
|
||||
mozilla::ipc::ScopedProcessHandle childHandle;
|
||||
#ifdef XP_MACOSX
|
||||
childHandle = aTopLevel->Process()->GetChildTask();
|
||||
#else
|
||||
if (!base::OpenPrivilegedProcessHandle(aTopLevel->OtherPid(),
|
||||
&childHandle.rwget())) {
|
||||
NS_WARNING("Failed to open child process handle.");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
nsCOMPtr<nsIFile> targetDump;
|
||||
if (CrashReporter::CreateMinidumpsAndPair(childHandle,
|
||||
mMainThread, // child thread id
|
||||
aPairName,
|
||||
aMinidumpToPair,
|
||||
getter_AddRefs(targetDump)) &&
|
||||
CrashReporter::GetIDFromMinidump(targetDump, mChildDumpID)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class Toplevel>
|
||||
inline bool
|
||||
CrashReporterParent::GenerateCrashReport(Toplevel* t,
|
||||
|
@ -279,25 +189,6 @@ CrashReporterParent::GenerateCompleteMinidump(Toplevel* t)
|
|||
return false;
|
||||
}
|
||||
|
||||
template<class Toplevel>
|
||||
/* static */ bool
|
||||
CrashReporterParent::CreateCrashReporter(Toplevel* actor)
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
NativeThreadId id;
|
||||
uint32_t processType;
|
||||
PCrashReporterParent* p =
|
||||
actor->CallPCrashReporterConstructor(&id, &processType);
|
||||
if (p) {
|
||||
static_cast<CrashReporterParent*>(p)->SetChildData(id, processType);
|
||||
} else {
|
||||
NS_ERROR("Error creating crash reporter actor");
|
||||
}
|
||||
return !!p;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -20,7 +20,7 @@ struct Mapping {
|
|||
};
|
||||
|
||||
async protocol PCrashReporter {
|
||||
manager PContent or PPluginModule;
|
||||
manager PContent;
|
||||
parent:
|
||||
async AnnotateCrashReport(nsCString key, nsCString data);
|
||||
async AppendAppNotes(nsCString data);
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
include protocol PPluginInstance;
|
||||
include protocol PPluginScriptableObject;
|
||||
include protocol PCrashReporter;
|
||||
include protocol PContent;
|
||||
include ProfilerTypes;
|
||||
|
||||
|
@ -37,7 +36,6 @@ struct PluginSettings
|
|||
intr protocol PPluginModule
|
||||
{
|
||||
manages PPluginInstance;
|
||||
manages PCrashReporter;
|
||||
|
||||
both:
|
||||
// Window-specific message which instructs the interrupt mechanism to enter
|
||||
|
@ -92,8 +90,8 @@ child:
|
|||
|
||||
async SetParentHangTimeout(uint32_t seconds);
|
||||
|
||||
intr PCrashReporter()
|
||||
returns (NativeThreadId tid, uint32_t processType);
|
||||
intr InitCrashReporter(Shmem shmem)
|
||||
returns (NativeThreadId tid);
|
||||
|
||||
/**
|
||||
* Control the Gecko Profiler in the plugin process.
|
||||
|
|
|
@ -50,14 +50,16 @@
|
|||
#include "PluginUtilsOSX.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "mozilla/ipc/CrashReporterClient.h"
|
||||
#endif
|
||||
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::plugins;
|
||||
using namespace mozilla::widget;
|
||||
using mozilla::dom::CrashReporterChild;
|
||||
using mozilla::dom::PCrashReporterChild;
|
||||
|
||||
#if defined(XP_WIN)
|
||||
const wchar_t * kFlashFullscreenClass = L"ShockwaveFlashFullScreen";
|
||||
|
@ -720,29 +722,13 @@ PluginModuleChild::RecvInitPluginModuleChild(Endpoint<PPluginModuleChild>&& aEnd
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
PCrashReporterChild*
|
||||
PluginModuleChild::AllocPCrashReporterChild(mozilla::dom::NativeThreadId* id,
|
||||
uint32_t* processType)
|
||||
{
|
||||
return new CrashReporterChild();
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleChild::DeallocPCrashReporterChild(PCrashReporterChild* actor)
|
||||
{
|
||||
delete actor;
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
PluginModuleChild::AnswerPCrashReporterConstructor(
|
||||
PCrashReporterChild* actor,
|
||||
mozilla::dom::NativeThreadId* id,
|
||||
uint32_t* processType)
|
||||
PluginModuleChild::AnswerInitCrashReporter(Shmem&& aShmem, mozilla::dom::NativeThreadId* aOutId)
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
*id = CrashReporter::CurrentThreadId();
|
||||
*processType = XRE_GetProcessType();
|
||||
CrashReporterClient::InitSingletonWithShmem(aShmem);
|
||||
*aOutId = CrashReporter::CurrentThreadId();
|
||||
#endif
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -775,6 +761,9 @@ PluginModuleChild::ActorDestroy(ActorDestroyReason why)
|
|||
|
||||
// doesn't matter why we're being destroyed; it's up to us to
|
||||
// initiate (clean) shutdown
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
CrashReporterClient::DestroySingleton();
|
||||
#endif
|
||||
XRE_ShutdownChildProcess();
|
||||
}
|
||||
|
||||
|
|
|
@ -46,17 +46,12 @@ typedef NS_NPAPIPLUGIN_CALLBACK(NPError, NP_PLUGINUNIXINIT) (const NPNetscapeFun
|
|||
typedef NS_NPAPIPLUGIN_CALLBACK(NPError, NP_PLUGINSHUTDOWN) (void);
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class PCrashReporterChild;
|
||||
} // namespace dom
|
||||
|
||||
namespace plugins {
|
||||
|
||||
class PluginInstanceChild;
|
||||
|
||||
class PluginModuleChild : public PPluginModuleChild
|
||||
{
|
||||
typedef mozilla::dom::PCrashReporterChild PCrashReporterChild;
|
||||
protected:
|
||||
virtual mozilla::ipc::RacyInterruptPolicy
|
||||
MediateInterruptRace(const MessageInfo& parent,
|
||||
|
@ -123,15 +118,8 @@ protected:
|
|||
virtual mozilla::ipc::IPCResult
|
||||
RecvSetParentHangTimeout(const uint32_t& aSeconds) override;
|
||||
|
||||
virtual PCrashReporterChild*
|
||||
AllocPCrashReporterChild(mozilla::dom::NativeThreadId* id,
|
||||
uint32_t* processType) override;
|
||||
virtual bool
|
||||
DeallocPCrashReporterChild(PCrashReporterChild* actor) override;
|
||||
virtual mozilla::ipc::IPCResult
|
||||
AnswerPCrashReporterConstructor(PCrashReporterChild* actor,
|
||||
mozilla::dom::NativeThreadId* id,
|
||||
uint32_t* processType) override;
|
||||
AnswerInitCrashReporter(Shmem&& aShmem, mozilla::dom::NativeThreadId* aId) override;
|
||||
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason why) override;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/PCrashReporterParent.h"
|
||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||
#include "mozilla/ipc/MessageChannel.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
|
@ -67,15 +66,14 @@ using mozilla::ProfileGatherer;
|
|||
#endif
|
||||
using mozilla::ipc::MessageChannel;
|
||||
using mozilla::ipc::GeckoChildProcessHost;
|
||||
using mozilla::dom::PCrashReporterParent;
|
||||
using mozilla::dom::CrashReporterParent;
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::plugins;
|
||||
using namespace mozilla::plugins::parent;
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "mozilla/dom/CrashReporterParent.h"
|
||||
#include "mozilla/ipc/CrashReporterClient.h"
|
||||
#include "mozilla/ipc/CrashReporterHost.h"
|
||||
|
||||
using namespace CrashReporter;
|
||||
#endif
|
||||
|
@ -598,25 +596,12 @@ PluginModuleChromeParent::OnProcessLaunched(const bool aSucceeded)
|
|||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
// If this fails, we're having IPC troubles, and we're doomed anyways.
|
||||
if (!CrashReporterParent::CreateCrashReporter(this)) {
|
||||
if (!InitCrashReporter()) {
|
||||
mShutdown = true;
|
||||
Close();
|
||||
OnInitFailure();
|
||||
return;
|
||||
}
|
||||
CrashReporterParent* crashReporter = CrashReporter();
|
||||
if (crashReporter) {
|
||||
crashReporter->AnnotateCrashReport(NS_LITERAL_CSTRING("AsyncPluginInit"),
|
||||
mIsStartingAsync ?
|
||||
NS_LITERAL_CSTRING("1") :
|
||||
NS_LITERAL_CSTRING("0"));
|
||||
}
|
||||
#ifdef XP_WIN
|
||||
{ // Scope for lock
|
||||
mozilla::MutexAutoLock lock(mCrashReporterMutex);
|
||||
mCrashReporter = CrashReporter();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN) && defined(_X86_)
|
||||
|
@ -686,6 +671,37 @@ PluginModuleChromeParent::WaitForIPCConnection()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleChromeParent::InitCrashReporter()
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
ipc::Shmem shmem;
|
||||
if (!ipc::CrashReporterClient::AllocShmem(this, &shmem)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NativeThreadId threadId;
|
||||
if (!CallInitCrashReporter(shmem, &threadId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
mozilla::MutexAutoLock lock(mCrashReporterMutex);
|
||||
mCrashReporter = MakeUnique<ipc::CrashReporterHost>(
|
||||
GeckoProcessType_Plugin,
|
||||
shmem,
|
||||
threadId);
|
||||
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("AsyncPluginInit"),
|
||||
mIsStartingAsync ?
|
||||
NS_LITERAL_CSTRING("1") :
|
||||
NS_LITERAL_CSTRING("0"));
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PluginModuleParent::PluginModuleParent(bool aIsChrome, bool aAllowAsyncInit)
|
||||
: mQuirks(QUIRKS_NOT_INITIALIZED)
|
||||
, mIsChrome(aIsChrome)
|
||||
|
@ -703,6 +719,9 @@ PluginModuleParent::PluginModuleParent(bool aIsChrome, bool aAllowAsyncInit)
|
|||
, mNPInitialized(false)
|
||||
, mIsNPShutdownPending(false)
|
||||
, mAsyncNewRv(NS_ERROR_NOT_INITIALIZED)
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
, mCrashReporterMutex("PluginModuleChromeParent::mCrashReporterMutex")
|
||||
#endif
|
||||
{
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AsyncPluginInit"),
|
||||
|
@ -752,10 +771,6 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath,
|
|||
, mHangUIParent(nullptr)
|
||||
, mHangUIEnabled(true)
|
||||
, mIsTimerReset(true)
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
, mCrashReporterMutex("PluginModuleChromeParent::mCrashReporterMutex")
|
||||
, mCrashReporter(nullptr)
|
||||
#endif
|
||||
#endif
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
, mFlashProcess1(0)
|
||||
|
@ -838,12 +853,11 @@ PluginModuleChromeParent::~PluginModuleChromeParent()
|
|||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
void
|
||||
PluginModuleChromeParent::WriteExtraDataForMinidump(AnnotationTable& notes)
|
||||
PluginModuleChromeParent::WriteExtraDataForMinidump()
|
||||
{
|
||||
#ifdef XP_WIN
|
||||
// mCrashReporterMutex is already held by the caller
|
||||
mCrashReporterMutex.AssertCurrentThreadOwns();
|
||||
#endif
|
||||
|
||||
typedef nsDependentCString CS;
|
||||
|
||||
// Get the plugin filename, try to get just the file leafname
|
||||
|
@ -853,27 +867,26 @@ PluginModuleChromeParent::WriteExtraDataForMinidump(AnnotationTable& notes)
|
|||
filePos = 0;
|
||||
else
|
||||
filePos++;
|
||||
notes.Put(NS_LITERAL_CSTRING("PluginFilename"), CS(pluginFile.substr(filePos).c_str()));
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginFilename"), CS(pluginFile.substr(filePos).c_str()));
|
||||
|
||||
notes.Put(NS_LITERAL_CSTRING("PluginName"), mPluginName);
|
||||
notes.Put(NS_LITERAL_CSTRING("PluginVersion"), mPluginVersion);
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginName"), mPluginName);
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginVersion"), mPluginVersion);
|
||||
|
||||
CrashReporterParent* crashReporter = CrashReporter();
|
||||
if (crashReporter) {
|
||||
if (mCrashReporter) {
|
||||
#ifdef XP_WIN
|
||||
if (mPluginCpuUsageOnHang.Length() > 0) {
|
||||
notes.Put(NS_LITERAL_CSTRING("NumberOfProcessors"),
|
||||
nsPrintfCString("%d", PR_GetNumberOfProcessors()));
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("NumberOfProcessors"),
|
||||
nsPrintfCString("%d", PR_GetNumberOfProcessors()));
|
||||
|
||||
nsCString cpuUsageStr;
|
||||
cpuUsageStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[0] * 100) / 100);
|
||||
notes.Put(NS_LITERAL_CSTRING("PluginCpuUsage"), cpuUsageStr);
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginCpuUsage"), cpuUsageStr);
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
for (uint32_t i=1; i<mPluginCpuUsageOnHang.Length(); ++i) {
|
||||
nsCString tempStr;
|
||||
tempStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[i] * 100) / 100);
|
||||
notes.Put(nsPrintfCString("CpuUsageFlashProcess%d", i), tempStr);
|
||||
mCrashReporter->AddNote(nsPrintfCString("CpuUsageFlashProcess%d", i), tempStr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1203,12 +1216,9 @@ PluginModuleChromeParent::TakeFullMinidump(base::ProcessId aContentPid,
|
|||
nsString& aDumpId)
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#ifdef XP_WIN
|
||||
mozilla::MutexAutoLock lock(mCrashReporterMutex);
|
||||
#endif // XP_WIN
|
||||
|
||||
CrashReporterParent* crashReporter = CrashReporter();
|
||||
if (!crashReporter) {
|
||||
if (!mCrashReporter) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1227,8 +1237,11 @@ PluginModuleChromeParent::TakeFullMinidump(base::ProcessId aContentPid,
|
|||
{
|
||||
// We have a single browser report, generate a new plugin process parent
|
||||
// report and pair it up with the browser report handed in.
|
||||
reportsReady = crashReporter->GenerateMinidumpAndPair(this, browserDumpFile,
|
||||
NS_LITERAL_CSTRING("browser"));
|
||||
reportsReady = mCrashReporter->GenerateMinidumpAndPair(
|
||||
this,
|
||||
browserDumpFile,
|
||||
NS_LITERAL_CSTRING("browser"));
|
||||
|
||||
if (!reportsReady) {
|
||||
browserDumpFile = nullptr;
|
||||
CrashReporter::DeleteMinidumpFilesForID(aBrowserDumpId);
|
||||
|
@ -1240,20 +1253,20 @@ PluginModuleChromeParent::TakeFullMinidump(base::ProcessId aContentPid,
|
|||
// the browser process, content process when running under e10s, and
|
||||
// various flash subprocesses if we're the flash module.
|
||||
if (!reportsReady) {
|
||||
reportsReady = crashReporter->GeneratePairedMinidump(this);
|
||||
reportsReady = mCrashReporter->GenerateMinidumpAndPair(
|
||||
this,
|
||||
nullptr, // Pair with a dump of this process and thread.
|
||||
NS_LITERAL_CSTRING("browser"));
|
||||
}
|
||||
|
||||
if (reportsReady) {
|
||||
// Important to set this here, it tells the ActorDestroy handler
|
||||
// that we have an existing crash report that needs to be finalized.
|
||||
mPluginDumpID = crashReporter->ChildDumpID();
|
||||
aDumpId = mPluginDumpID;
|
||||
aDumpId = mCrashReporter->MinidumpID();
|
||||
PLUGIN_LOG_DEBUG(
|
||||
("generated paired browser/plugin minidumps: %s)",
|
||||
NS_ConvertUTF16toUTF8(mPluginDumpID).get()));
|
||||
NS_ConvertUTF16toUTF8(aDumpId).get()));
|
||||
nsAutoCString additionalDumps("browser");
|
||||
nsCOMPtr<nsIFile> pluginDumpFile;
|
||||
if (GetMinidumpForID(mPluginDumpID, getter_AddRefs(pluginDumpFile)) &&
|
||||
if (GetMinidumpForID(aDumpId, getter_AddRefs(pluginDumpFile)) &&
|
||||
pluginDumpFile) {
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
// If we have handles to the flash sandbox processes on Windows,
|
||||
|
@ -1276,7 +1289,7 @@ PluginModuleChromeParent::TakeFullMinidump(base::ProcessId aContentPid,
|
|||
}
|
||||
}
|
||||
}
|
||||
crashReporter->AnnotateCrashReport(
|
||||
mCrashReporter->AddNote(
|
||||
NS_LITERAL_CSTRING("additional_minidumps"),
|
||||
additionalDumps);
|
||||
} else {
|
||||
|
@ -1294,33 +1307,28 @@ PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop,
|
|||
#ifdef MOZ_CRASHREPORTER
|
||||
// Start by taking a full minidump if necessary, this is done early
|
||||
// because it also needs to lock the mCrashReporterMutex and Mutex doesn't
|
||||
// support recrusive locking.
|
||||
// support recursive locking.
|
||||
nsAutoString dumpId;
|
||||
if (aDumpId.IsEmpty()) {
|
||||
TakeFullMinidump(aContentPid, EmptyString(), dumpId);
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
mozilla::MutexAutoLock lock(mCrashReporterMutex);
|
||||
CrashReporterParent* crashReporter = mCrashReporter;
|
||||
if (!crashReporter) {
|
||||
if (!mCrashReporter) {
|
||||
// If mCrashReporter is null then the hang has ended, the plugin module
|
||||
// is shutting down. There's nothing to do here.
|
||||
return;
|
||||
}
|
||||
#else
|
||||
CrashReporterParent* crashReporter = CrashReporter();
|
||||
#endif // XP_WIN
|
||||
crashReporter->AnnotateCrashReport(NS_LITERAL_CSTRING("PluginHang"),
|
||||
NS_LITERAL_CSTRING("1"));
|
||||
crashReporter->AnnotateCrashReport(NS_LITERAL_CSTRING("HangMonitorDescription"),
|
||||
aMonitorDescription);
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginHang"),
|
||||
NS_LITERAL_CSTRING("1"));
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("HangMonitorDescription"),
|
||||
aMonitorDescription);
|
||||
#ifdef XP_WIN
|
||||
if (mHangUIParent) {
|
||||
unsigned int hangUIDuration = mHangUIParent->LastShowDurationMs();
|
||||
if (hangUIDuration) {
|
||||
nsPrintfCString strHangUIDuration("%u", hangUIDuration);
|
||||
crashReporter->AnnotateCrashReport(
|
||||
mCrashReporter->AddNote(
|
||||
NS_LITERAL_CSTRING("PluginHangUIDuration"),
|
||||
strHangUIDuration);
|
||||
}
|
||||
|
@ -1501,12 +1509,6 @@ PluginModuleChromeParent::OnHangUIContinue()
|
|||
#endif // XP_WIN
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
CrashReporterParent*
|
||||
PluginModuleChromeParent::CrashReporter()
|
||||
{
|
||||
return static_cast<CrashReporterParent*>(LoneManagedOrNullAsserts(ManagedPCrashReporterParent()));
|
||||
}
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
static void
|
||||
RemoveMinidump(nsIFile* minidump)
|
||||
|
@ -1526,31 +1528,26 @@ RemoveMinidump(nsIFile* minidump)
|
|||
void
|
||||
PluginModuleChromeParent::ProcessFirstMinidump()
|
||||
{
|
||||
#ifdef XP_WIN
|
||||
mozilla::MutexAutoLock lock(mCrashReporterMutex);
|
||||
#endif
|
||||
CrashReporterParent* crashReporter = CrashReporter();
|
||||
if (!crashReporter)
|
||||
|
||||
if (!mCrashReporter)
|
||||
return;
|
||||
|
||||
AnnotationTable notes(4);
|
||||
WriteExtraDataForMinidump(notes);
|
||||
WriteExtraDataForMinidump();
|
||||
|
||||
if (!mPluginDumpID.IsEmpty()) {
|
||||
// mPluginDumpID may be set in TerminateChildProcess, which means the
|
||||
if (mCrashReporter->HasMinidump()) {
|
||||
// A minidump may be set in TerminateChildProcess, which means the
|
||||
// process hang monitor has already collected a 3-way browser, plugin,
|
||||
// content crash report. If so, update the existing report with our
|
||||
// annotations and finalize it. If not, fall through for standard
|
||||
// plugin crash report handling.
|
||||
crashReporter->GenerateChildData(¬es);
|
||||
crashReporter->FinalizeChildData();
|
||||
mCrashReporter->FinalizeCrashReport();
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t sequence = UINT32_MAX;
|
||||
nsCOMPtr<nsIFile> dumpFile;
|
||||
nsAutoCString flashProcessType;
|
||||
TakeMinidump(getter_AddRefs(dumpFile), &sequence);
|
||||
RefPtr<nsIFile> dumpFile = mCrashReporter->TakeCrashedChildMinidump(OtherPid(), &sequence);
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
nsCOMPtr<nsIFile> childDumpFile;
|
||||
|
@ -1560,7 +1557,9 @@ PluginModuleChromeParent::ProcessFirstMinidump()
|
|||
TakeMinidumpForChild(mFlashProcess1,
|
||||
getter_AddRefs(childDumpFile),
|
||||
&childSequence)) {
|
||||
if (childSequence < sequence) {
|
||||
if (childSequence < sequence &&
|
||||
mCrashReporter->AdoptMinidump(childDumpFile))
|
||||
{
|
||||
RemoveMinidump(dumpFile);
|
||||
dumpFile = childDumpFile;
|
||||
sequence = childSequence;
|
||||
|
@ -1574,7 +1573,9 @@ PluginModuleChromeParent::ProcessFirstMinidump()
|
|||
TakeMinidumpForChild(mFlashProcess2,
|
||||
getter_AddRefs(childDumpFile),
|
||||
&childSequence)) {
|
||||
if (childSequence < sequence) {
|
||||
if (childSequence < sequence &&
|
||||
mCrashReporter->AdoptMinidump(childDumpFile))
|
||||
{
|
||||
RemoveMinidump(dumpFile);
|
||||
dumpFile = childDumpFile;
|
||||
sequence = childSequence;
|
||||
|
@ -1592,13 +1593,12 @@ PluginModuleChromeParent::ProcessFirstMinidump()
|
|||
}
|
||||
|
||||
PLUGIN_LOG_DEBUG(("got child minidump: %s",
|
||||
NS_ConvertUTF16toUTF8(mPluginDumpID).get()));
|
||||
NS_ConvertUTF16toUTF8(mCrashReporter->MinidumpID()).get()));
|
||||
|
||||
GetIDFromMinidump(dumpFile, mPluginDumpID);
|
||||
if (!flashProcessType.IsEmpty()) {
|
||||
notes.Put(NS_LITERAL_CSTRING("FlashProcessDump"), flashProcessType);
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("FlashProcessDump"), flashProcessType);
|
||||
}
|
||||
crashReporter->GenerateCrashReportForMinidump(dumpFile, ¬es);
|
||||
mCrashReporter->FinalizeCrashReport();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1672,8 +1672,18 @@ PluginModuleParent::NotifyPluginCrashed()
|
|||
return;
|
||||
}
|
||||
|
||||
if (mPlugin)
|
||||
mPlugin->PluginCrashed(mPluginDumpID, mBrowserDumpID);
|
||||
if (!mPlugin) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsString dumpID;
|
||||
nsString browserDumpID;
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
if (mCrashReporter && mCrashReporter->HasMinidump()) {
|
||||
dumpID = mCrashReporter->MinidumpID();
|
||||
}
|
||||
#endif
|
||||
mPlugin->PluginCrashed(dumpID, browserDumpID);
|
||||
}
|
||||
|
||||
PPluginInstanceParent*
|
||||
|
@ -2988,45 +2998,6 @@ PluginModuleParent::RecvPluginHideWindow(const uint32_t& aWindowId)
|
|||
#endif
|
||||
}
|
||||
|
||||
PCrashReporterParent*
|
||||
PluginModuleParent::AllocPCrashReporterParent(mozilla::dom::NativeThreadId* id,
|
||||
uint32_t* processType)
|
||||
{
|
||||
MOZ_CRASH("unreachable");
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleParent::DeallocPCrashReporterParent(PCrashReporterParent* actor)
|
||||
{
|
||||
MOZ_CRASH("unreachable");
|
||||
}
|
||||
|
||||
PCrashReporterParent*
|
||||
PluginModuleChromeParent::AllocPCrashReporterParent(mozilla::dom::NativeThreadId* id,
|
||||
uint32_t* processType)
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
return new CrashReporterParent();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleChromeParent::DeallocPCrashReporterParent(PCrashReporterParent* actor)
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#ifdef XP_WIN
|
||||
mozilla::MutexAutoLock lock(mCrashReporterMutex);
|
||||
if (actor == static_cast<PCrashReporterParent*>(mCrashReporter)) {
|
||||
mCrashReporter = nullptr;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
delete actor;
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
PluginModuleParent::RecvSetCursor(const NSCursorInfo& aCursorInfo)
|
||||
{
|
||||
|
|
|
@ -37,11 +37,10 @@ namespace mozilla {
|
|||
#ifdef MOZ_GECKO_PROFILER
|
||||
class ProfileGatherer;
|
||||
#endif
|
||||
namespace dom {
|
||||
class PCrashReporterParent;
|
||||
class CrashReporterParent;
|
||||
} // namespace dom
|
||||
|
||||
namespace ipc {
|
||||
class CrashReporterHost;
|
||||
} // namespace ipc
|
||||
namespace layers {
|
||||
class TextureClientRecycleAllocator;
|
||||
} // namespace layers
|
||||
|
@ -86,8 +85,6 @@ class PluginModuleParent
|
|||
{
|
||||
protected:
|
||||
typedef mozilla::PluginLibrary PluginLibrary;
|
||||
typedef mozilla::dom::PCrashReporterParent PCrashReporterParent;
|
||||
typedef mozilla::dom::CrashReporterParent CrashReporterParent;
|
||||
|
||||
PPluginInstanceParent*
|
||||
AllocPPluginInstanceParent(const nsCString& aMimeType,
|
||||
|
@ -168,12 +165,6 @@ protected:
|
|||
virtual mozilla::ipc::IPCResult
|
||||
RecvPluginHideWindow(const uint32_t& aWindowId) override;
|
||||
|
||||
virtual PCrashReporterParent*
|
||||
AllocPCrashReporterParent(mozilla::dom::NativeThreadId* id,
|
||||
uint32_t* processType) override;
|
||||
virtual bool
|
||||
DeallocPCrashReporterParent(PCrashReporterParent* actor) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvSetCursor(const NSCursorInfo& aCursorInfo) override;
|
||||
|
||||
|
@ -339,8 +330,6 @@ protected:
|
|||
NPPluginFuncs* mNPPIface;
|
||||
nsNPAPIPlugin* mPlugin;
|
||||
ipc::TaskFactory<PluginModuleParent> mTaskFactory;
|
||||
nsString mPluginDumpID;
|
||||
nsString mBrowserDumpID;
|
||||
nsString mHangID;
|
||||
RefPtr<nsIObserver> mProfilerObserver;
|
||||
TimeDuration mTimeBlocked;
|
||||
|
@ -358,7 +347,6 @@ protected:
|
|||
bool
|
||||
GetPluginDetails();
|
||||
|
||||
friend class mozilla::dom::CrashReporterParent;
|
||||
friend class mozilla::plugins::PluginAsyncSurrogate;
|
||||
|
||||
bool mIsStartingAsync;
|
||||
|
@ -370,6 +358,17 @@ protected:
|
|||
|
||||
RefPtr<layers::TextureClientRecycleAllocator> mTextureAllocatorForDirectBitmap;
|
||||
RefPtr<layers::TextureClientRecycleAllocator> mTextureAllocatorForDXGISurface;
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
/**
|
||||
* This mutex protects the crash reporter when the Plugin Hang UI event
|
||||
* handler is executing off main thread. It is intended to protect both
|
||||
* the mCrashReporter variable in addition to the CrashReporterHost object
|
||||
* that mCrashReporter refers to.
|
||||
*/
|
||||
mozilla::Mutex mCrashReporterMutex;
|
||||
UniquePtr<ipc::CrashReporterHost> mCrashReporter;
|
||||
#endif // MOZ_CRASHREPORTER
|
||||
};
|
||||
|
||||
class PluginModuleContentParent : public PluginModuleParent
|
||||
|
@ -410,6 +409,7 @@ class PluginModuleChromeParent
|
|||
: public PluginModuleParent
|
||||
, public mozilla::HangMonitor::Annotator
|
||||
{
|
||||
friend class mozilla::ipc::CrashReporterHost;
|
||||
public:
|
||||
/**
|
||||
* LoadModule
|
||||
|
@ -526,15 +526,9 @@ private:
|
|||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
void ProcessFirstMinidump();
|
||||
void WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes);
|
||||
void WriteExtraDataForMinidump();
|
||||
#endif
|
||||
|
||||
virtual PCrashReporterParent*
|
||||
AllocPCrashReporterParent(mozilla::dom::NativeThreadId* id,
|
||||
uint32_t* processType) override;
|
||||
virtual bool
|
||||
DeallocPCrashReporterParent(PCrashReporterParent* actor) override;
|
||||
|
||||
PluginProcessParent* Process() const { return mSubprocess; }
|
||||
base::ProcessHandle ChildProcessHandle() { return mSubprocess->GetChildProcessHandle(); }
|
||||
|
||||
|
@ -555,8 +549,6 @@ private:
|
|||
int32_t aSandboxLevel,
|
||||
bool aAllowAsyncInit);
|
||||
|
||||
CrashReporterParent* CrashReporter();
|
||||
|
||||
void CleanupFromTimeout(const bool aByHangUI);
|
||||
|
||||
virtual void UpdatePluginTimeout() override;
|
||||
|
@ -569,6 +561,8 @@ private:
|
|||
void RegisterSettingsCallbacks();
|
||||
void UnregisterSettingsCallbacks();
|
||||
|
||||
bool InitCrashReporter();
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvNotifyContentModuleDestroyed() override;
|
||||
|
||||
static void CachedSettingChanged(const char* aPref, void* aModule);
|
||||
|
@ -596,17 +590,6 @@ private:
|
|||
PluginHangUIParent *mHangUIParent;
|
||||
bool mHangUIEnabled;
|
||||
bool mIsTimerReset;
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
/**
|
||||
* This mutex protects the crash reporter when the Plugin Hang UI event
|
||||
* handler is executing off main thread. It is intended to protect both
|
||||
* the mCrashReporter variable in addition to the CrashReporterParent object
|
||||
* that mCrashReporter refers to.
|
||||
*/
|
||||
mozilla::Mutex mCrashReporterMutex;
|
||||
CrashReporterParent* mCrashReporter;
|
||||
#endif // MOZ_CRASHREPORTER
|
||||
|
||||
|
||||
/**
|
||||
* Launches the Plugin Hang UI.
|
||||
|
@ -625,7 +608,6 @@ private:
|
|||
FinishHangUI();
|
||||
#endif
|
||||
|
||||
friend class mozilla::dom::CrashReporterParent;
|
||||
friend class mozilla::plugins::PluginAsyncSurrogate;
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
|
|
|
@ -33,16 +33,33 @@ CrashReporterHost::CrashReporterHost(GeckoProcessType aProcessType,
|
|||
bool
|
||||
CrashReporterHost::GenerateCrashReport(base::ProcessId aPid)
|
||||
{
|
||||
RefPtr<nsIFile> crashDump;
|
||||
if (!XRE_TakeMinidumpForChild(aPid, getter_AddRefs(crashDump), nullptr)) {
|
||||
return false;
|
||||
}
|
||||
if (!CrashReporter::GetIDFromMinidump(crashDump, mDumpID)) {
|
||||
if (!TakeCrashedChildMinidump(aPid, nullptr)) {
|
||||
return false;
|
||||
}
|
||||
return FinalizeCrashReport();
|
||||
}
|
||||
|
||||
RefPtr<nsIFile>
|
||||
CrashReporterHost::TakeCrashedChildMinidump(base::ProcessId aPid, uint32_t* aOutSequence)
|
||||
{
|
||||
MOZ_ASSERT(!HasMinidump());
|
||||
|
||||
RefPtr<nsIFile> crashDump;
|
||||
if (!XRE_TakeMinidumpForChild(aPid, getter_AddRefs(crashDump), aOutSequence)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!AdoptMinidump(crashDump)) {
|
||||
return nullptr;
|
||||
}
|
||||
return crashDump.get();
|
||||
}
|
||||
|
||||
bool
|
||||
CrashReporterHost::AdoptMinidump(nsIFile* aFile)
|
||||
{
|
||||
return CrashReporter::GetIDFromMinidump(aFile, mDumpID);
|
||||
}
|
||||
|
||||
bool
|
||||
CrashReporterHost::FinalizeCrashReport()
|
||||
{
|
||||
|
@ -73,11 +90,16 @@ CrashReporterHost::FinalizeCrashReport()
|
|||
SprintfLiteral(startTime, "%lld", static_cast<long long>(mStartTime));
|
||||
notes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime));
|
||||
|
||||
CrashReporterMetadataShmem::ReadAppNotes(mShmem, ¬es);
|
||||
// We might not have shmem (for example, when running crashreporter tests).
|
||||
if (mShmem.IsReadable()) {
|
||||
CrashReporterMetadataShmem::ReadAppNotes(mShmem, ¬es);
|
||||
}
|
||||
CrashReporter::AppendExtraData(mDumpID, mExtraNotes);
|
||||
CrashReporter::AppendExtraData(mDumpID, notes);
|
||||
|
||||
NotifyCrashService(mProcessType, mDumpID, ¬es);
|
||||
// Use mExtraNotes, since NotifyCrashService looks for "PluginHang" which is
|
||||
// set in the parent process.
|
||||
NotifyCrashService(mProcessType, mDumpID, &mExtraNotes);
|
||||
|
||||
mFinalized = true;
|
||||
return true;
|
||||
|
|
|
@ -36,11 +36,53 @@ public:
|
|||
// the process has a minidump attached and we were able to generate a report.
|
||||
bool GenerateCrashReport(base::ProcessId aPid);
|
||||
|
||||
// Given an existing minidump for a crashed child process, take ownership of
|
||||
// it from IPDL. After this, FinalizeCrashReport may be called.
|
||||
RefPtr<nsIFile> TakeCrashedChildMinidump(base::ProcessId aPid, uint32_t* aOutSequence);
|
||||
|
||||
// Replace the stored minidump with a new one. After this,
|
||||
// FinalizeCrashReport may be called.
|
||||
bool AdoptMinidump(nsIFile* aFile);
|
||||
|
||||
// If a minidump was already captured (e.g. via the hang reporter), this
|
||||
// finalizes the existing report by attaching metadata and notifying the
|
||||
// crash service.
|
||||
bool FinalizeCrashReport();
|
||||
|
||||
// Generate a paired minidump. This does not take the crash report, as
|
||||
// GenerateCrashReport does. After this, FinalizeCrashReport may be called.
|
||||
//
|
||||
// This calls TakeCrashedChildMinidump and FinalizeCrashReport.
|
||||
template <typename Toplevel>
|
||||
bool GenerateMinidumpAndPair(Toplevel* aToplevelProtocol,
|
||||
nsIFile* aMinidumpToPair,
|
||||
const nsACString& aPairName)
|
||||
{
|
||||
ScopedProcessHandle childHandle;
|
||||
#ifdef XP_MACOSX
|
||||
childHandle = aToplevelProtocol->Process()->GetChildTask();
|
||||
#else
|
||||
if (!base::OpenPrivilegedProcessHandle(aToplevelProtocol->OtherPid(),
|
||||
&childHandle.rwget()))
|
||||
{
|
||||
NS_WARNING("Failed to open child process handle.");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIFile> targetDump;
|
||||
if (!CrashReporter::CreateMinidumpsAndPair(childHandle,
|
||||
mThreadId,
|
||||
aPairName,
|
||||
aMinidumpToPair,
|
||||
getter_AddRefs(targetDump)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return CrashReporter::GetIDFromMinidump(targetDump, mDumpID);
|
||||
}
|
||||
|
||||
// This is a static helper function to notify the crash service that a
|
||||
// crash has occurred. When PCrashReporter is removed, we can make this
|
||||
// a member function. This can be called from any thread, and if not
|
||||
|
|
Загрузка…
Ссылка в новой задаче