1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "CrashReporterHost.h"
8 #include "mozilla/dom/Promise.h"
9 #include "mozilla/Sprintf.h"
10 #include "mozilla/SyncRunnable.h"
11 #include "mozilla/Telemetry.h"
12 #include "nsServiceManagerUtils.h"
13 #include "nsICrashService.h"
14 #include "nsXULAppAPI.h"
20 CrashReporterHost::CrashReporterHost(GeckoProcessType aProcessType
,
21 CrashReporter::ThreadId aThreadId
)
22 : mProcessType(aProcessType
),
24 mStartTime(::time(nullptr)),
27 bool CrashReporterHost::GenerateCrashReport(base::ProcessId aPid
) {
28 if (!TakeCrashedChildMinidump(aPid
, nullptr)) {
32 FinalizeCrashReport();
33 RecordCrash(mProcessType
, nsICrashService::CRASH_TYPE_CRASH
, mDumpID
);
37 RefPtr
<nsIFile
> CrashReporterHost::TakeCrashedChildMinidump(
38 base::ProcessId aPid
, uint32_t* aOutSequence
) {
39 CrashReporter::AnnotationTable annotations
;
40 MOZ_ASSERT(!HasMinidump());
42 RefPtr
<nsIFile
> crashDump
;
43 if (!CrashReporter::TakeMinidumpForChild(aPid
, getter_AddRefs(crashDump
),
44 annotations
, aOutSequence
)) {
47 if (!AdoptMinidump(crashDump
, annotations
)) {
53 bool CrashReporterHost::AdoptMinidump(nsIFile
* aFile
,
54 const AnnotationTable
& aAnnotations
) {
55 if (!CrashReporter::GetIDFromMinidump(aFile
, mDumpID
)) {
59 MergeCrashAnnotations(mExtraAnnotations
, aAnnotations
);
63 void CrashReporterHost::FinalizeCrashReport() {
64 MOZ_ASSERT(!mFinalized
);
65 MOZ_ASSERT(HasMinidump());
67 mExtraAnnotations
[CrashReporter::Annotation::ProcessType
] =
68 XRE_ChildProcessTypeToAnnotation(mProcessType
);
71 SprintfLiteral(startTime
, "%lld", static_cast<long long>(mStartTime
));
72 mExtraAnnotations
[CrashReporter::Annotation::StartupTime
] =
73 nsDependentCString(startTime
);
75 CrashReporter::WriteExtraFile(mDumpID
, mExtraAnnotations
);
79 void CrashReporterHost::DeleteCrashReport() {
80 if (mFinalized
&& HasMinidump()) {
81 CrashReporter::DeleteMinidumpFilesForID(mDumpID
, Some(u
"browser"_ns
));
86 void CrashReporterHost::RecordCrash(GeckoProcessType aProcessType
,
88 const nsString
& aChildDumpID
) {
89 if (!NS_IsMainThread()) {
90 RefPtr
<Runnable
> runnable
= NS_NewRunnableFunction(
91 "ipc::CrashReporterHost::RecordCrash", [&]() -> void {
92 CrashReporterHost::RecordCrash(aProcessType
, aCrashType
,
95 RefPtr
<nsIThread
> mainThread
= do_GetMainThread();
96 SyncRunnable::DispatchToThread(mainThread
, runnable
);
100 RecordCrashWithTelemetry(aProcessType
, aCrashType
);
101 NotifyCrashService(aProcessType
, aCrashType
, aChildDumpID
);
105 void CrashReporterHost::RecordCrashWithTelemetry(GeckoProcessType aProcessType
,
106 int32_t aCrashType
) {
109 switch (aProcessType
) {
110 #define GECKO_PROCESS_TYPE(enum_value, enum_name, string_name, proc_typename, \
111 process_bin_type, procinfo_typename, \
112 webidl_typename, allcaps_name) \
113 case GeckoProcessType_##enum_name: \
114 key.AssignLiteral(string_name); \
116 #include "mozilla/GeckoProcessTypes.h"
117 #undef GECKO_PROCESS_TYPE
118 // We can't really hit this, thanks to the above switch, but having it
119 // here will placate the compiler.
121 MOZ_ASSERT_UNREACHABLE("unknown process type");
124 Telemetry::Accumulate(Telemetry::SUBPROCESS_CRASHES_WITH_DUMP
, key
, 1);
128 void CrashReporterHost::NotifyCrashService(GeckoProcessType aProcessType
,
130 const nsString
& aChildDumpID
) {
131 MOZ_ASSERT(!aChildDumpID
.IsEmpty());
133 nsCOMPtr
<nsICrashService
> crashService
=
134 do_GetService("@mozilla.org/crashservice;1");
141 switch (aProcessType
) {
142 case GeckoProcessType_IPDLUnitTest
:
143 case GeckoProcessType_Default
:
144 NS_ERROR("unknown process type");
147 processType
= (int)aProcessType
;
151 RefPtr
<dom::Promise
> promise
;
152 crashService
->AddCrash(processType
, aCrashType
, aChildDumpID
,
153 getter_AddRefs(promise
));
156 void CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey
,
158 mExtraAnnotations
[aKey
] = aValue
? "1"_ns
: "0"_ns
;
161 void CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey
,
163 nsAutoCString valueString
;
164 valueString
.AppendInt(aValue
);
165 mExtraAnnotations
[aKey
] = valueString
;
168 void CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey
,
169 unsigned int aValue
) {
170 nsAutoCString valueString
;
171 valueString
.AppendInt(aValue
);
172 mExtraAnnotations
[aKey
] = valueString
;
175 void CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey
,
176 const nsACString
& aValue
) {
177 mExtraAnnotations
[aKey
] = aValue
;
181 } // namespace mozilla