void
PluginModuleParent::WriteExtraDataForMinidump(AnnotationTable& notes)
{
    typedef nsDependentCString CS;

    // 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(""));

    CrashReporterParent* crashReporter = CrashReporter();
    if (crashReporter) {
        const nsString& hangID = crashReporter->HangID();
        if (!hangID.IsEmpty())
            notes.Put(CS("HangID"), NS_ConvertUTF16toUTF8(hangID));
    }
}
Example #2
0
static bool
WriteExtraData(nsILocalFile* extraFile,
               const AnnotationTable& data,
               const Blacklist& blacklist,
               bool writeCrashTime=false,
               bool truncate=false)
{
  PRFileDesc* fd;
  PRIntn truncOrAppend = truncate ? PR_TRUNCATE : PR_APPEND;
  nsresult rv = 
    extraFile->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE | truncOrAppend,
                                0600, &fd);
  if (NS_FAILED(rv))
    return false;

  EnumerateAnnotationsContext ctx = { blacklist, fd };
  data.EnumerateRead(EnumerateAnnotations, &ctx);

  if (writeCrashTime) {
    time_t crashTime = time(NULL);
    char crashTimeString[32];
    XP_TTOA(crashTime, crashTimeString, 10);

    WriteAnnotation(fd,
                    nsDependentCString("CrashTime"),
                    nsDependentCString(crashTimeString));
  }

  PR_Close(fd);
  return true;
}
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
    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(NS_LITERAL_CSTRING("PluginFilename"), CS(pluginFile.substr(filePos).c_str()));

    nsCString pluginName;
    nsCString pluginVersion;

    nsRefPtr<nsPluginHost> ph = nsPluginHost::GetInst();
    if (ph) {
        nsPluginTag* tag = ph->TagForPlugin(mPlugin);
        if (tag) {
            pluginName = tag->mName;
            pluginVersion = tag->mVersion;
        }
    }
        
    notes.Put(NS_LITERAL_CSTRING("PluginName"), pluginName);
    notes.Put(NS_LITERAL_CSTRING("PluginVersion"), pluginVersion);

    CrashReporterParent* crashReporter = CrashReporter();
    if (crashReporter) {
#ifdef XP_WIN
        if (mPluginCpuUsageOnHang.Length() > 0) {
            notes.Put(NS_LITERAL_CSTRING("NumberOfProcessors"),
                      nsPrintfCString("%d", PR_GetNumberOfProcessors()));

            nsCString cpuUsageStr;
            cpuUsageStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[0] * 100) / 100);
            notes.Put(NS_LITERAL_CSTRING("PluginCpuUsage"), cpuUsageStr);

#ifdef MOZ_CRASHREPORTER_INJECTOR
            for (uint32_t i=1; i<mPluginCpuUsageOnHang.Length(); ++i) {
                nsCString tempStr;
                tempStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[i] * 100) / 100);
                notes.Put(nsPrintfCString("CpuUsageFlashProcess%d", i), tempStr);
            }
#endif
        }
#endif
    }
}
void
PluginModuleParent::WriteExtraDataForMinidump(AnnotationTable& notes)
{
    typedef nsDependentCString CS;

    // 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(""));

    CrashReporterParent* crashReporter = CrashReporter();
    if (crashReporter) {
        const nsString& hangID = crashReporter->HangID();
        if (!hangID.IsEmpty()) {
            notes.Put(CS("HangID"), NS_ConvertUTF16toUTF8(hangID));
#ifdef XP_WIN
            if (mPluginCpuUsageOnHang.Length() > 0) {
              notes.Put(CS("NumberOfProcessors"),
                        nsPrintfCString("%d", PR_GetNumberOfProcessors()));

              nsCString cpuUsageStr;
              cpuUsageStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[0] * 100) / 100);
              notes.Put(CS("PluginCpuUsage"), cpuUsageStr);

#ifdef MOZ_CRASHREPORTER_INJECTOR
              for (uint32_t i=1; i<mPluginCpuUsageOnHang.Length(); ++i) {
                nsCString tempStr;
                tempStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[i] * 100) / 100);
                notes.Put(nsPrintfCString("CpuUsageFlashProcess%d", i), tempStr);
              }
#endif
            }
#endif
        }
    }
}
void
PluginModuleParent::ProcessFirstMinidump()
{
    CrashReporterParent* crashReporter = CrashReporter();
    if (!crashReporter)
        return;

    AnnotationTable notes;
    notes.Init(4);
    WriteExtraDataForMinidump(notes);
        
    if (!mPluginDumpID.IsEmpty() && !mBrowserDumpID.IsEmpty()) {
        crashReporter->GenerateHangCrashReport(&notes);
        return;
    }

    uint32_t sequence = PR_UINT32_MAX;
    nsCOMPtr<nsIFile> dumpFile;
    nsAutoCString flashProcessType;
    TakeMinidump(getter_AddRefs(dumpFile), &sequence);

#ifdef MOZ_CRASHREPORTER_INJECTOR
    nsCOMPtr<nsIFile> childDumpFile;
    uint32_t childSequence;

    if (mFlashProcess1 &&
        TakeMinidumpForChild(mFlashProcess1,
                             getter_AddRefs(childDumpFile),
                             &childSequence)) {
        if (childSequence < sequence) {
            RemoveMinidump(dumpFile);
            dumpFile = childDumpFile;
            sequence = childSequence;
            flashProcessType.AssignLiteral("Broker");
        }
        else {
            RemoveMinidump(childDumpFile);
        }
    }
    if (mFlashProcess2 &&
        TakeMinidumpForChild(mFlashProcess2,
                             getter_AddRefs(childDumpFile),
                             &childSequence)) {
        if (childSequence < sequence) {
            RemoveMinidump(dumpFile);
            dumpFile = childDumpFile;
            sequence = childSequence;
            flashProcessType.AssignLiteral("Sandbox");
        }
        else {
            RemoveMinidump(childDumpFile);
        }
    }
#endif

    if (!dumpFile) {
        NS_WARNING("[PluginModuleParent::ActorDestroy] abnormal shutdown without minidump!");
        return;
    }

    PLUGIN_LOG_DEBUG(("got child minidump: %s",
                      NS_ConvertUTF16toUTF8(mPluginDumpID).get()));

    GetIDFromMinidump(dumpFile, mPluginDumpID);
    if (!flashProcessType.IsEmpty()) {
        notes.Put(NS_LITERAL_CSTRING("FlashProcessDump"), flashProcessType);
    }
    crashReporter->GenerateCrashReportForMinidump(dumpFile, &notes);
}