diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 7cfd823bf1c2..e7fc4d59cf9e 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -214,6 +214,10 @@ static const char* sClipboardTextFlavors[] = { kUnicodeMime }; using base::ChildPrivileges; using base::KillProcess; + +#ifdef MOZ_CRASHREPORTER +using namespace CrashReporter; +#endif using namespace mozilla::dom::bluetooth; using namespace mozilla::dom::cellbroadcast; using namespace mozilla::dom::devicestorage; @@ -1797,7 +1801,16 @@ ContentParent::ActorDestroy(ActorDestroyReason why) NS_ConvertUTF16toUTF8(mAppManifestURL)); } - crashReporter->GenerateCrashReport(this, nullptr); + if (mCalledKillHard) { + // We killed the child with KillHard, so two minidumps should already + // exist - one for the content process, and one for the browser process. + // The "main" minidump of this crash report is the content processes, + // and we use GenerateChildData to annotate our crash report with + // information about the child process. + crashReporter->GenerateChildData(nullptr); + } else { + crashReporter->GenerateCrashReport(this, nullptr); + } nsAutoString dumpID(crashReporter->ChildDumpID()); props->SetPropertyAsAString(NS_LITERAL_STRING("dumpID"), dumpID); @@ -3090,10 +3103,31 @@ ContentParent::KillHard() } mCalledKillHard = true; mForceKillTask = nullptr; - // This ensures the process is eventually killed, but doesn't - // immediately KILLITWITHFIRE because we want to get a minidump if - // possible. After a timeout though, the process is forceably - // killed. + +#ifdef MOZ_CRASHREPORTER + if (ManagedPCrashReporterParent().Length() > 0) { + CrashReporterParent* crashReporter = + static_cast(ManagedPCrashReporterParent()[0]); + + // We're about to kill the child process associated with this + // ContentParent. Something has gone wrong to get us here, + // so we generate a minidump to be potentially submitted in + // a crash report. ContentParent::ActorDestroy is where the + // actual report gets generated, once the child process has + // finally died. + if (crashReporter->GeneratePairedMinidump(this)) { + // GeneratePairedMinidump created two minidumps for us - the main + // one is for the content process we're about to kill, and the other + // one is for the main browser process. That second one is the extra + // minidump tagging along, so we have to tell the crash reporter that + // it exists and is being appended. + nsAutoCString additionalDumps("browser"); + crashReporter->AnnotateCrashReport( + NS_LITERAL_CSTRING("additional_minidumps"), + additionalDumps); + } + } +#endif if (!KillProcess(OtherProcess(), 1, false)) { NS_WARNING("failed to kill subprocess!"); }