Bug 581341 - Part 1: Make crash report annotation work OOP and subsume existing workarounds. r=cjones

This commit is contained in:
Josh Matthews
2011-06-08 15:56:31 -04:00
parent e72b63d240
commit 3c736ad9bb
21 changed files with 450 additions and 168 deletions

View File

@@ -56,12 +56,13 @@
#include "mozilla/ipc/SyncChannel.h"
#include "mozilla/plugins/PluginModuleParent.h"
#include "mozilla/plugins/BrowserStreamParent.h"
#include "mozilla/dom/PCrashReporterParent.h"
#include "PluginIdentifierParent.h"
#include "nsAutoPtr.h"
#include "nsCRT.h"
#ifdef MOZ_CRASHREPORTER
#include "nsExceptionHandler.h"
#include "mozilla/dom/CrashReporterParent.h"
#endif
#include "nsNPAPIPlugin.h"
#include "nsILocalFile.h"
@@ -74,6 +75,8 @@ using base::KillProcess;
using mozilla::PluginLibrary;
using mozilla::ipc::SyncChannel;
using mozilla::dom::PCrashReporterParent;
using mozilla::dom::CrashReporterParent;
using namespace mozilla;
using namespace mozilla::plugins;
@@ -116,13 +119,11 @@ PluginModuleParent::LoadModule(const char* aFilePath)
PluginModuleParent::PluginModuleParent(const char* aFilePath)
: mSubprocess(new PluginProcessParent(aFilePath))
, mPluginThread(0)
, mShutdown(false)
, mClearSiteDataSupported(false)
, mGetSitesWithDataSupported(false)
, mNPNIface(NULL)
, mPlugin(NULL)
, mProcessStartTime(time(NULL))
, mTaskFactory(this)
{
NS_ASSERTION(mSubprocess, "Out of memory!");
@@ -161,20 +162,10 @@ PluginModuleParent::~PluginModuleParent()
#ifdef MOZ_CRASHREPORTER
void
PluginModuleParent::WritePluginExtraDataForMinidump(const nsAString& id)
PluginModuleParent::WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes)
{
typedef nsDependentCString CS;
CrashReporter::AnnotationTable notes;
if (!notes.Init(32))
return;
notes.Put(CS("ProcessType"), CS("plugin"));
char startTime[32];
sprintf(startTime, "%lld", static_cast<PRInt64>(mProcessStartTime));
notes.Put(CS("StartupTime"), CS(startTime));
// Get the plugin filename, try to get just the file leafname
const std::string& pluginFile = mSubprocess->GetPluginFilePath();
size_t filePos = pluginFile.rfind(FILE_PATH_SEPARATOR);
@@ -189,39 +180,12 @@ PluginModuleParent::WritePluginExtraDataForMinidump(const nsAString& id)
notes.Put(CS("PluginName"), CS(""));
notes.Put(CS("PluginVersion"), CS(""));
if (!mCrashNotes.IsEmpty())
notes.Put(CS("Notes"), CS(mCrashNotes.get()));
if (!mHangID.IsEmpty())
notes.Put(CS("HangID"), NS_ConvertUTF16toUTF8(mHangID));
if (!CrashReporter::AppendExtraData(id, notes))
NS_WARNING("problem appending plugin data to .extra");
}
void
PluginModuleParent::WriteExtraDataForHang()
{
// this writes HangID
WritePluginExtraDataForMinidump(mPluginDumpID);
CrashReporter::AnnotationTable notes;
if (!notes.Init(4))
return;
notes.Put(nsDependentCString("HangID"), NS_ConvertUTF16toUTF8(mHangID));
if (!CrashReporter::AppendExtraData(mBrowserDumpID, notes))
NS_WARNING("problem appending browser data to .extra");
const nsString& hangID = CrashReporter()->HangID();
if (!hangID.IsEmpty())
notes.Put(CS("HangID"), NS_ConvertUTF16toUTF8(hangID));
}
#endif // MOZ_CRASHREPORTER
bool
PluginModuleParent::RecvAppendNotesToCrashReport(const nsCString& aNotes)
{
mCrashNotes.Append(aNotes);
return true;
}
int
PluginModuleParent::TimeoutChanged(const char* aPref, void* aModule)
{
@@ -248,29 +212,16 @@ bool
PluginModuleParent::ShouldContinueFromReplyTimeout()
{
#ifdef MOZ_CRASHREPORTER
nsCOMPtr<nsILocalFile> pluginDump;
nsCOMPtr<nsILocalFile> browserDump;
CrashReporter::ProcessHandle child;
#ifdef XP_MACOSX
child = mSubprocess->GetChildTask();
#else
child = OtherProcess();
#endif
if (CrashReporter::CreatePairedMinidumps(child,
mPluginThread,
&mHangID,
getter_AddRefs(pluginDump),
getter_AddRefs(browserDump)) &&
CrashReporter::GetIDFromMinidump(pluginDump, mPluginDumpID) &&
CrashReporter::GetIDFromMinidump(browserDump, mBrowserDumpID)) {
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(mHangID).get()));
}
else {
("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
@@ -288,21 +239,33 @@ PluginModuleParent::ShouldContinueFromReplyTimeout()
return false;
}
#ifdef MOZ_CRASHREPORTER
CrashReporterParent*
PluginModuleParent::CrashReporter()
{
return static_cast<CrashReporterParent*>(ManagedPCrashReporterParent()[0]);
}
#endif
void
PluginModuleParent::ActorDestroy(ActorDestroyReason why)
{
switch (why) {
case AbnormalShutdown: {
#ifdef MOZ_CRASHREPORTER
nsCOMPtr<nsILocalFile> pluginDump;
if (TakeMinidump(getter_AddRefs(pluginDump)) &&
CrashReporter::GetIDFromMinidump(pluginDump, mPluginDumpID)) {
CrashReporterParent* crashReporter = CrashReporter();
CrashReporter::AnnotationTable notes;
notes.Init(4);
WriteExtraDataForMinidump(notes);
if (crashReporter->GenerateCrashReport(this, &notes)) {
mPluginDumpID = crashReporter->ChildDumpID();
PLUGIN_LOG_DEBUG(("got child minidump: %s",
NS_ConvertUTF16toUTF8(mPluginDumpID).get()));
WritePluginExtraDataForMinidump(mPluginDumpID);
}
else if (!mPluginDumpID.IsEmpty() && !mBrowserDumpID.IsEmpty()) {
WriteExtraDataForHang();
crashReporter->GenerateHangCrashReport(&notes);
}
else {
NS_WARNING("[PluginModuleParent::ActorDestroy] abnormal shutdown without minidump!");
@@ -763,7 +726,7 @@ PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs
return NS_ERROR_FAILURE;
}
if (!CallNP_Initialize(&mPluginThread, error)) {
if (!CallNP_Initialize(error)) {
return NS_ERROR_FAILURE;
}
else if (*error != NPERR_NO_ERROR) {
@@ -787,7 +750,7 @@ PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error)
return NS_ERROR_FAILURE;
}
if (!CallNP_Initialize(&mPluginThread, error))
if (!CallNP_Initialize(error))
return NS_ERROR_FAILURE;
#if defined XP_WIN && MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
@@ -1074,6 +1037,24 @@ PluginModuleParent::RecvPluginHideWindow(const uint32_t& aWindowId)
#endif
}
PCrashReporterParent*
PluginModuleParent::AllocPCrashReporter(const NativeThreadId& tid,
const PRUint32& processType)
{
#ifdef MOZ_CRASHREPORTER
return new CrashReporterParent(tid, processType);
#else
return nsnull;
#endif
}
bool
PluginModuleParent::DeallocPCrashReporter(PCrashReporterParent* actor)
{
delete actor;
return true;
}
bool
PluginModuleParent::RecvSetCursor(const NSCursorInfo& aCursorInfo)
{