Bug 1262852 - Create a minidump of the plugin process as soon as possible during hang r=jimm
This commit is contained in:
@@ -353,26 +353,50 @@ bool PluginModuleMapping::sIsLoadModuleOnStack = false;
|
||||
|
||||
} // namespace
|
||||
|
||||
static PluginModuleChromeParent*
|
||||
PluginModuleChromeParentForId(const uint32_t aPluginId)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
|
||||
nsPluginTag* pluginTag = host->PluginWithId(aPluginId);
|
||||
if (!pluginTag || !pluginTag->mPlugin) {
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<nsNPAPIPlugin> plugin = pluginTag->mPlugin;
|
||||
|
||||
return static_cast<PluginModuleChromeParent*>(plugin->GetLibrary());
|
||||
}
|
||||
|
||||
void
|
||||
mozilla::plugins::TakeFullMinidump(uint32_t aPluginId,
|
||||
base::ProcessId aContentProcessId,
|
||||
const nsAString& aBrowserDumpId,
|
||||
nsString& aDumpId)
|
||||
{
|
||||
PluginModuleChromeParent* chromeParent =
|
||||
PluginModuleChromeParentForId(aPluginId);
|
||||
|
||||
if (chromeParent) {
|
||||
chromeParent->TakeFullMinidump(aContentProcessId, aBrowserDumpId, aDumpId);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mozilla::plugins::TerminatePlugin(uint32_t aPluginId,
|
||||
base::ProcessId aContentProcessId,
|
||||
const nsCString& aMonitorDescription,
|
||||
const nsAString& aBrowserDumpId)
|
||||
const nsAString& aDumpId)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
PluginModuleChromeParent* chromeParent =
|
||||
PluginModuleChromeParentForId(aPluginId);
|
||||
|
||||
RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
|
||||
nsPluginTag* pluginTag = host->PluginWithId(aPluginId);
|
||||
if (!pluginTag || !pluginTag->mPlugin) {
|
||||
return;
|
||||
}
|
||||
RefPtr<nsNPAPIPlugin> plugin = pluginTag->mPlugin;
|
||||
PluginModuleChromeParent* chromeParent =
|
||||
static_cast<PluginModuleChromeParent*>(plugin->GetLibrary());
|
||||
if (chromeParent) {
|
||||
chromeParent->TerminateChildProcess(MessageLoop::current(),
|
||||
aContentProcessId,
|
||||
aMonitorDescription,
|
||||
aBrowserDumpId);
|
||||
aDumpId);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ PluginLibrary*
|
||||
@@ -1198,38 +1222,19 @@ PluginModuleContentParent::OnExitedSyncSend()
|
||||
}
|
||||
|
||||
void
|
||||
PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop,
|
||||
base::ProcessId aContentPid,
|
||||
const nsCString& aMonitorDescription,
|
||||
const nsAString& aBrowserDumpId)
|
||||
PluginModuleChromeParent::TakeFullMinidump(base::ProcessId aContentPid,
|
||||
const nsAString& aBrowserDumpId,
|
||||
nsString& aDumpId)
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#ifdef XP_WIN
|
||||
mozilla::MutexAutoLock lock(mCrashReporterMutex);
|
||||
CrashReporterParent* crashReporter = mCrashReporter;
|
||||
#endif // XP_WIN
|
||||
|
||||
CrashReporterParent* crashReporter = CrashReporter();
|
||||
if (!crashReporter) {
|
||||
// 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
|
||||
crashReporter->AnnotateCrashReport(NS_LITERAL_CSTRING("PluginHang"),
|
||||
NS_LITERAL_CSTRING("1"));
|
||||
crashReporter->AnnotateCrashReport(NS_LITERAL_CSTRING("HangMonitorDescription"),
|
||||
aMonitorDescription);
|
||||
#ifdef XP_WIN
|
||||
if (mHangUIParent) {
|
||||
unsigned int hangUIDuration = mHangUIParent->LastShowDurationMs();
|
||||
if (hangUIDuration) {
|
||||
nsPrintfCString strHangUIDuration("%u", hangUIDuration);
|
||||
crashReporter->AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("PluginHangUIDuration"),
|
||||
strHangUIDuration);
|
||||
}
|
||||
}
|
||||
#endif // XP_WIN
|
||||
|
||||
bool reportsReady = false;
|
||||
|
||||
@@ -1266,6 +1271,7 @@ PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop,
|
||||
// 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;
|
||||
PLUGIN_LOG_DEBUG(
|
||||
("generated paired browser/plugin minidumps: %s)",
|
||||
NS_ConvertUTF16toUTF8(mPluginDumpID).get()));
|
||||
@@ -1284,7 +1290,7 @@ PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop,
|
||||
NS_LITERAL_CSTRING("flash2"))) {
|
||||
additionalDumps.AppendLiteral(",flash2");
|
||||
}
|
||||
#endif
|
||||
#endif // MOZ_CRASHREPORTER_INJECTOR
|
||||
if (aContentPid != mozilla::ipc::kInvalidProcessId) {
|
||||
// Include the content process minidump
|
||||
if (CreatePluginMinidump(aContentPid, 0,
|
||||
@@ -1300,7 +1306,51 @@ PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop,
|
||||
} else {
|
||||
NS_WARNING("failed to capture paired minidumps from hang");
|
||||
}
|
||||
#endif
|
||||
#endif // MOZ_CRASHREPORTER
|
||||
}
|
||||
|
||||
void
|
||||
PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop,
|
||||
base::ProcessId aContentPid,
|
||||
const nsCString& aMonitorDescription,
|
||||
const nsAString& aDumpId)
|
||||
{
|
||||
#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.
|
||||
nsAutoString dumpId;
|
||||
if (aDumpId.IsEmpty()) {
|
||||
TakeFullMinidump(aContentPid, EmptyString(), dumpId);
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
mozilla::MutexAutoLock lock(mCrashReporterMutex);
|
||||
CrashReporterParent* crashReporter = mCrashReporter;
|
||||
if (!crashReporter) {
|
||||
// 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);
|
||||
#ifdef XP_WIN
|
||||
if (mHangUIParent) {
|
||||
unsigned int hangUIDuration = mHangUIParent->LastShowDurationMs();
|
||||
if (hangUIDuration) {
|
||||
nsPrintfCString strHangUIDuration("%u", hangUIDuration);
|
||||
crashReporter->AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("PluginHangUIDuration"),
|
||||
strHangUIDuration);
|
||||
}
|
||||
}
|
||||
#endif // XP_WIN
|
||||
#endif // MOZ_CRASHREPORTER
|
||||
|
||||
mozilla::ipc::ScopedProcessHandle geckoChildProcess;
|
||||
bool childOpened = base::OpenProcessHandle(OtherPid(),
|
||||
|
||||
Reference in New Issue
Block a user