void
PluginModuleParent::OnCrash(DWORD processID, const nsAString& aDumpID)
{
    if (!mPluginDumpID.IsEmpty()) {
        // One process has already crashed: we assume that the first-to-crash
        // is the interesting one
        return;
    }

    mPluginDumpID = aDumpID;

    CrashReporter::AnnotationTable notes;
    notes.Init(4);
    WriteExtraDataForMinidump(notes);
    notes.Put(NS_LITERAL_CSTRING("ProcessType"), NS_LITERAL_CSTRING("plugin"));
    if (processID == mFlashProcess1) {
        notes.Put(NS_LITERAL_CSTRING("FlashProcessDump"),
                  NS_LITERAL_CSTRING("Broker"));
    }
    else if (processID == mFlashProcess2) {
        notes.Put(NS_LITERAL_CSTRING("FlashProcessDump"),
                  NS_LITERAL_CSTRING("Sandbox"));
    }
    else {
        NS_ERROR("Got minidump for Flash process neither broker nor sandbox.");
    }

    CrashReporter::AppendExtraData(aDumpID, notes);
    MessageLoop::current()->PostTask(
        FROM_HERE,
        mTaskFactory.NewRunnableMethod(
            &PluginModuleParent::CleanupFromTimeout));

    KillProcess(OtherProcess(), 1, false);
}
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");
}
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(&notes);
        }
        else if (!mPluginDumpID.IsEmpty()) {
            // Nothing to do, we've already written this minidump in
            // PluginModuleParent::OnCrash
        }
        else if (crashReporter->GenerateCrashReport(this, &notes)) {
            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
PluginModuleParent::WritePluginExtraDataForMinidump(const nsAString& id)
{
    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);
    if (filePos == std::string::npos)
        filePos = 0;
    else
        filePos++;
    notes.Put(CS("PluginFilename"), CS(pluginFile.substr(filePos).c_str()));

    //TODO: add plugin name and version: bug 539841
    // (as PluginName, PluginVersion)
    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");
}