forked from mozilla/gecko-dev
-
Notifications
You must be signed in to change notification settings - Fork 2
/
CrashReporterParent.h
171 lines (154 loc) · 4.83 KB
/
CrashReporterParent.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set sw=4 ts=8 et tw=80 :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/PCrashReporterParent.h"
#include "mozilla/dom/TabMessageUtils.h"
#include "nsXULAppAPI.h"
#include "nsIFile.h"
#ifdef MOZ_CRASHREPORTER
#include "nsExceptionHandler.h"
#endif
namespace mozilla {
namespace dom {
class ProcessReporter;
class CrashReporterParent :
public PCrashReporterParent
{
#ifdef MOZ_CRASHREPORTER
typedef CrashReporter::AnnotationTable AnnotationTable;
#endif
public:
CrashReporterParent();
virtual ~CrashReporterParent();
#ifdef MOZ_CRASHREPORTER
/* Attempt to generate a parent/child pair of minidumps from the given
toplevel actor in the event of a hang. Returns true if successful,
false otherwise.
*/
template<class Toplevel>
bool
GeneratePairedMinidump(Toplevel* t);
/* Attempt to create a bare-bones crash report for a hang, along with extra
process-specific annotations present in the given AnnotationTable. Returns
true if successful, false otherwise.
*/
bool
GenerateHangCrashReport(const AnnotationTable* processNotes);
/* Attempt to create a bare-bones crash report, along with extra process-
specific annotations present in the given AnnotationTable. Returns true if
successful, false otherwise.
*/
template<class Toplevel>
bool
GenerateCrashReport(Toplevel* t, const AnnotationTable* processNotes);
bool
GenerateCrashReportForMinidump(nsIFile* minidump,
const AnnotationTable* processNotes);
/* Instantiate a new crash reporter actor from a given parent that manages
the protocol.
*/
template<class Toplevel>
static bool CreateCrashReporter(Toplevel* actor);
#endif
/* Initialize this reporter with data from the child process */
void
SetChildData(const NativeThreadId& id, const uint32_t& processType);
/* Returns the shared hang ID of a parent/child paired minidump.
GeneratePairedMinidump must be called first.
*/
const nsString& HangID() {
return mHangID;
}
/* Returns the ID of the parent minidump.
GeneratePairedMinidump must be called first.
*/
const nsString& ParentDumpID() {
return mParentDumpID;
}
/* Returns the ID of the child minidump.
GeneratePairedMinidump or GenerateCrashReport must be called first.
*/
const nsString& ChildDumpID() {
return mChildDumpID;
}
protected:
virtual void ActorDestroy(ActorDestroyReason why);
virtual bool
RecvAddLibraryMappings(const InfallibleTArray<Mapping>& m);
virtual bool
RecvAnnotateCrashReport(const nsCString& key, const nsCString& data);
virtual bool
RecvAppendAppNotes(const nsCString& data);
#ifdef MOZ_CRASHREPORTER
bool
GenerateChildData(const AnnotationTable* processNotes);
AnnotationTable mNotes;
#endif
nsCString mAppNotes;
nsString mHangID;
nsString mChildDumpID;
nsString mParentDumpID;
NativeThreadId mMainThread;
time_t mStartTime;
uint32_t mProcessType;
bool mInitialized;
};
#ifdef MOZ_CRASHREPORTER
template<class Toplevel>
inline bool
CrashReporterParent::GeneratePairedMinidump(Toplevel* t)
{
CrashReporter::ProcessHandle child;
#ifdef XP_MACOSX
child = t->Process()->GetChildTask();
#else
child = t->OtherProcess();
#endif
nsCOMPtr<nsIFile> childDump;
nsCOMPtr<nsIFile> parentDump;
if (CrashReporter::CreatePairedMinidumps(child,
mMainThread,
&mHangID,
getter_AddRefs(childDump),
getter_AddRefs(parentDump)) &&
CrashReporter::GetIDFromMinidump(childDump, mChildDumpID) &&
CrashReporter::GetIDFromMinidump(parentDump, mParentDumpID)) {
return true;
}
return false;
}
template<class Toplevel>
inline bool
CrashReporterParent::GenerateCrashReport(Toplevel* t,
const AnnotationTable* processNotes)
{
nsCOMPtr<nsIFile> crashDump;
if (t->TakeMinidump(getter_AddRefs(crashDump), NULL) &&
CrashReporter::GetIDFromMinidump(crashDump, mChildDumpID)) {
return GenerateChildData(processNotes);
}
return false;
}
template<class Toplevel>
/* static */ bool
CrashReporterParent::CreateCrashReporter(Toplevel* actor)
{
#ifdef MOZ_CRASHREPORTER
NativeThreadId id;
uint32_t processType;
PCrashReporterParent* p =
actor->CallPCrashReporterConstructor(&id, &processType);
if (p) {
static_cast<CrashReporterParent*>(p)->SetChildData(id, processType);
} else {
NS_ERROR("Error creating crash reporter actor");
}
return !!p;
#endif
return false;
}
#endif
} // namespace dom
} // namespace mozilla