diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 5810fd9aa6f1..1a191bb02a70 100755 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -111,6 +111,10 @@ PluginModuleParent::LoadModule(const char* aFilePath) parent->mShutdown = true; return nullptr; } +#ifdef XP_WIN + mozilla::MutexAutoLock lock(parent->mCrashReporterMutex); + parent->mCrashReporter = parent->CrashReporter(); +#endif #endif return parent.forget(); @@ -130,6 +134,10 @@ PluginModuleParent::PluginModuleParent(const char* aFilePath) , mHangUIParent(nullptr) , mHangUIEnabled(true) , mIsTimerReset(true) +#ifdef MOZ_CRASHREPORTER + , mCrashReporterMutex("PluginModuleParent::mCrashReporterMutex") + , mCrashReporter(nullptr) +#endif #endif #ifdef MOZ_CRASHREPORTER_INJECTOR , mFlashProcess1(0) @@ -194,6 +202,10 @@ PluginModuleParent::~PluginModuleParent() void PluginModuleParent::WriteExtraDataForMinidump(AnnotationTable& notes) { +#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 @@ -419,7 +431,17 @@ void PluginModuleParent::TerminateChildProcess(MessageLoop* aMsgLoop) { #ifdef MOZ_CRASHREPORTER +#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 crashReporter->AnnotateCrashReport(NS_LITERAL_CSTRING("PluginHang"), NS_LITERAL_CSTRING("1")); #ifdef XP_WIN @@ -636,6 +658,9 @@ RemoveMinidump(nsIFile* minidump) void PluginModuleParent::ProcessFirstMinidump() { +#ifdef XP_WIN + mozilla::MutexAutoLock lock(mCrashReporterMutex); +#endif CrashReporterParent* crashReporter = CrashReporter(); if (!crashReporter) return; @@ -1535,6 +1560,12 @@ PluginModuleParent::AllocPCrashReporterParent(mozilla::dom::NativeThreadId* id, bool PluginModuleParent::DeallocPCrashReporterParent(PCrashReporterParent* actor) { +#ifdef XP_WIN + mozilla::MutexAutoLock lock(mCrashReporterMutex); + if (actor == static_cast(mCrashReporter)) { + mCrashReporter = nullptr; + } +#endif delete actor; return true; } diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index c3c970e8bcd8..09c15f1b7ff0 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -314,6 +314,17 @@ 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 + void EvaluateHangUIState(const bool aReset);