bool PluginModuleParent::ShouldContinueFromReplyTimeout() { #ifdef MOZ_CRASHREPORTER CrashReporterParent* crashReporter = CrashReporter(); if (crashReporter->GeneratePairedMinidump(this)) { mBrowserDumpID = crashReporter->ParentDumpID(); mPluginDumpID = crashReporter->ChildDumpID(); PLUGIN_LOG_DEBUG( ("generated paired browser/plugin minidumps: %s/%s (ID=%s)", NS_ConvertUTF16toUTF8(mBrowserDumpID).get(), NS_ConvertUTF16toUTF8(mPluginDumpID).get(), NS_ConvertUTF16toUTF8(crashReporter->HangID()).get())); } else { NS_WARNING("failed to capture paired minidumps from hang"); } #endif // this must run before the error notification from the channel, // or not at all MessageLoop::current()->PostTask( FROM_HERE, mTaskFactory.NewRunnableMethod( &PluginModuleParent::CleanupFromTimeout)); if (!KillProcess(OtherProcess(), 1, false)) NS_WARNING("failed to kill subprocess!"); return false; }
bool PluginModuleParent::ShouldContinueFromReplyTimeout() { #ifdef MOZ_CRASHREPORTER CrashReporterParent* crashReporter = CrashReporter(); crashReporter->AnnotateCrashReport(NS_LITERAL_CSTRING("PluginHang"), NS_LITERAL_CSTRING("1")); if (crashReporter->GeneratePairedMinidump(this)) { mPluginDumpID = crashReporter->ChildDumpID(); PLUGIN_LOG_DEBUG( ("generated paired browser/plugin minidumps: %s)", NS_ConvertUTF16toUTF8(mPluginDumpID).get())); crashReporter->AnnotateCrashReport( NS_LITERAL_CSTRING("additional_minidumps"), NS_LITERAL_CSTRING("browser")); // TODO: collect Flash minidumps here } else { NS_WARNING("failed to capture paired minidumps from hang"); } #endif #ifdef XP_WIN // collect cpu usage for plugin processes InfallibleTArray<base::ProcessHandle> processHandles; base::ProcessHandle handle; processHandles.AppendElement(OtherProcess()); #ifdef MOZ_CRASHREPORTER_INJECTOR if (mFlashProcess1 && base::OpenProcessHandle(mFlashProcess1, &handle)) { processHandles.AppendElement(handle); } if (mFlashProcess2 && base::OpenProcessHandle(mFlashProcess2, &handle)) { processHandles.AppendElement(handle); } #endif if (!GetProcessCpuUsage(processHandles, mPluginCpuUsageOnHang)) { mPluginCpuUsageOnHang.Clear(); } #endif // this must run before the error notification from the channel, // or not at all MessageLoop::current()->PostTask( FROM_HERE, mTaskFactory.NewRunnableMethod( &PluginModuleParent::CleanupFromTimeout)); if (!KillProcess(OtherProcess(), 1, false)) NS_WARNING("failed to kill subprocess!"); return false; }
void PluginModuleParent::ActorDestroy(ActorDestroyReason why) { switch (why) { case AbnormalShutdown: { #ifdef MOZ_CRASHREPORTER CrashReporterParent* crashReporter = CrashReporter(); CrashReporter::AnnotationTable notes; notes.Init(4); WriteExtraDataForMinidump(notes); if (!mPluginDumpID.IsEmpty() && !mBrowserDumpID.IsEmpty()) { crashReporter->GenerateHangCrashReport(¬es); } else if (!mPluginDumpID.IsEmpty()) { // Nothing to do, we've already written this minidump in // PluginModuleParent::OnCrash } else if (crashReporter->GenerateCrashReport(this, ¬es)) { mPluginDumpID = crashReporter->ChildDumpID(); PLUGIN_LOG_DEBUG(("got child minidump: %s", NS_ConvertUTF16toUTF8(mPluginDumpID).get())); } else { NS_WARNING("[PluginModuleParent::ActorDestroy] abnormal shutdown without minidump!"); } #endif mShutdown = true; // Defer the PluginCrashed method so that we don't re-enter // and potentially modify the actor child list while enumerating it. if (mPlugin) MessageLoop::current()->PostTask( FROM_HERE, mTaskFactory.NewRunnableMethod( &PluginModuleParent::NotifyPluginCrashed)); break; } case NormalShutdown: mShutdown = true; break; default: NS_ERROR("Unexpected shutdown reason for toplevel actor."); } }
void ContentParent::ActorDestroy(ActorDestroyReason why) { nsCOMPtr<nsIThreadObserver> kungFuDeathGrip(static_cast<nsIThreadObserver*>(this)); nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); if (obs) { obs->RemoveObserver(static_cast<nsIObserver*>(this), "xpcom-shutdown"); obs->RemoveObserver(static_cast<nsIObserver*>(this), "memory-pressure"); obs->RemoveObserver(static_cast<nsIObserver*>(this), "child-memory-reporter-request"); obs->RemoveObserver(static_cast<nsIObserver*>(this), NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC); obs->RemoveObserver(static_cast<nsIObserver*>(this), "child-gc-request"); obs->RemoveObserver(static_cast<nsIObserver*>(this), "child-cc-request"); #ifdef ACCESSIBILITY obs->RemoveObserver(static_cast<nsIObserver*>(this), "a11y-init-or-shutdown"); #endif } mMessageManager->Disconnect(); // clear the child memory reporters InfallibleTArray<MemoryReport> empty; SetChildMemoryReporters(empty); // remove the global remote preferences observers nsCOMPtr<nsIPrefBranch2> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID)); if (prefs) { prefs->RemoveObserver("", this); } RecvRemoveGeolocationListener(); RecvRemoveDeviceMotionListener(); nsCOMPtr<nsIThreadInternal> threadInt(do_QueryInterface(NS_GetCurrentThread())); if (threadInt) threadInt->RemoveObserver(this); if (mRunToCompletionDepth) mRunToCompletionDepth = 0; if (gContentParents) { gContentParents->RemoveElement(this); if (!gContentParents->Length()) { delete gContentParents; gContentParents = NULL; } } mIsAlive = false; if (obs) { nsRefPtr<nsHashPropertyBag> props = new nsHashPropertyBag(); props->Init(); if (AbnormalShutdown == why) { props->SetPropertyAsBool(NS_LITERAL_STRING("abnormal"), true); #ifdef MOZ_CRASHREPORTER MOZ_ASSERT(ManagedPCrashReporterParent().Length() > 0); CrashReporterParent* crashReporter = static_cast<CrashReporterParent*>(ManagedPCrashReporterParent()[0]); crashReporter->GenerateCrashReport(this, NULL); nsAutoString dumpID(crashReporter->ChildDumpID()); props->SetPropertyAsAString(NS_LITERAL_STRING("dumpID"), dumpID); #endif obs->NotifyObservers((nsIPropertyBag2*) props, "ipc:content-shutdown", nsnull); } } MessageLoop::current()-> PostTask(FROM_HERE, NewRunnableFunction(DelayedDeleteSubprocess, mSubprocess)); mSubprocess = NULL; // IPDL rules require actors to live on past ActorDestroy, but it // may be that the kungFuDeathGrip above is the last reference to // |this|. If so, when we go out of scope here, we're deleted and // all hell breaks loose. // // This runnable ensures that a reference to |this| lives on at // least until after the current task finishes running. NS_DispatchToCurrentThread(new DelayedDeleteContentParentTask(this)); }