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)); } }
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(¬es); 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, ¬es); }