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 632f80c98c
commit cea50ef339
21 changed files with 531 additions and 169 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;
@@ -111,19 +114,22 @@ PluginModuleParent::LoadModule(const char* aFilePath)
parent->mSubprocess->GetChildProcessHandle());
TimeoutChanged(kChildTimeoutPref, parent);
#ifdef MOZ_CRASHREPORTER
CrashReporterParent::CreateCrashReporter(parent.get());
#endif
return parent.forget();
}
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!");
@@ -164,20 +170,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);
@@ -192,39 +188,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)
{
@@ -254,29 +223,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
@@ -294,21 +250,34 @@ PluginModuleParent::ShouldContinueFromReplyTimeout()
return false;
}
#ifdef MOZ_CRASHREPORTER
CrashReporterParent*
PluginModuleParent::CrashReporter()
{
MOZ_ASSERT(ManagedPCrashReporterParent().Length() > 0);
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!");
@@ -781,7 +750,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) {
@@ -805,7 +774,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
@@ -1106,6 +1075,24 @@ PluginModuleParent::RecvPluginHideWindow(const uint32_t& aWindowId)
#endif
}
PCrashReporterParent*
PluginModuleParent::AllocPCrashReporter(mozilla::dom::NativeThreadId* id,
PRUint32* processType)
{
#ifdef MOZ_CRASHREPORTER
return new CrashReporterParent();
#else
return nsnull;
#endif
}
bool
PluginModuleParent::DeallocPCrashReporter(PCrashReporterParent* actor)
{
delete actor;
return true;
}
bool
PluginModuleParent::RecvSetCursor(const NSCursorInfo& aCursorInfo)
{