|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * vim: set sw=4 ts=8 et 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/. */ |
|
6 |
|
7 #ifndef mozilla_dom_CrashReporterParent_h |
|
8 #define mozilla_dom_CrashReporterParent_h |
|
9 |
|
10 #include "mozilla/dom/PCrashReporterParent.h" |
|
11 #include "mozilla/dom/TabMessageUtils.h" |
|
12 #include "nsIFile.h" |
|
13 #ifdef MOZ_CRASHREPORTER |
|
14 #include "nsExceptionHandler.h" |
|
15 #include "nsDataHashtable.h" |
|
16 #endif |
|
17 |
|
18 namespace mozilla { |
|
19 namespace dom { |
|
20 class ProcessReporter; |
|
21 |
|
22 class CrashReporterParent : |
|
23 public PCrashReporterParent |
|
24 { |
|
25 #ifdef MOZ_CRASHREPORTER |
|
26 typedef CrashReporter::AnnotationTable AnnotationTable; |
|
27 #endif |
|
28 public: |
|
29 CrashReporterParent(); |
|
30 virtual ~CrashReporterParent(); |
|
31 |
|
32 #ifdef MOZ_CRASHREPORTER |
|
33 /* Attempt to generate a parent/child pair of minidumps from the given |
|
34 toplevel actor in the event of a hang. Returns true if successful, |
|
35 false otherwise. |
|
36 */ |
|
37 template<class Toplevel> |
|
38 bool |
|
39 GeneratePairedMinidump(Toplevel* t); |
|
40 |
|
41 /* Attempt to create a bare-bones crash report, along with extra process- |
|
42 specific annotations present in the given AnnotationTable. Returns true if |
|
43 successful, false otherwise. |
|
44 */ |
|
45 template<class Toplevel> |
|
46 bool |
|
47 GenerateCrashReport(Toplevel* t, const AnnotationTable* processNotes); |
|
48 |
|
49 /** |
|
50 * Add the .extra data for an existing crash report. |
|
51 */ |
|
52 bool |
|
53 GenerateChildData(const AnnotationTable* processNotes); |
|
54 |
|
55 bool |
|
56 GenerateCrashReportForMinidump(nsIFile* minidump, |
|
57 const AnnotationTable* processNotes); |
|
58 |
|
59 /* Instantiate a new crash reporter actor from a given parent that manages |
|
60 the protocol. |
|
61 */ |
|
62 template<class Toplevel> |
|
63 static bool CreateCrashReporter(Toplevel* actor); |
|
64 #endif |
|
65 /* Initialize this reporter with data from the child process */ |
|
66 void |
|
67 SetChildData(const NativeThreadId& id, const uint32_t& processType); |
|
68 |
|
69 /* Returns the ID of the child minidump. |
|
70 GeneratePairedMinidump or GenerateCrashReport must be called first. |
|
71 */ |
|
72 const nsString& ChildDumpID() { |
|
73 return mChildDumpID; |
|
74 } |
|
75 |
|
76 void |
|
77 AnnotateCrashReport(const nsCString& key, const nsCString& data); |
|
78 |
|
79 protected: |
|
80 virtual bool |
|
81 RecvAnnotateCrashReport(const nsCString& key, const nsCString& data) MOZ_OVERRIDE { |
|
82 AnnotateCrashReport(key, data); |
|
83 return true; |
|
84 } |
|
85 virtual bool |
|
86 RecvAppendAppNotes(const nsCString& data) MOZ_OVERRIDE; |
|
87 virtual mozilla::ipc::IProtocol* |
|
88 CloneProtocol(Channel* aChannel, |
|
89 mozilla::ipc::ProtocolCloneContext *aCtx) MOZ_OVERRIDE; |
|
90 |
|
91 #ifdef MOZ_CRASHREPORTER |
|
92 AnnotationTable mNotes; |
|
93 #endif |
|
94 nsCString mAppNotes; |
|
95 nsString mChildDumpID; |
|
96 NativeThreadId mMainThread; |
|
97 time_t mStartTime; |
|
98 uint32_t mProcessType; |
|
99 bool mInitialized; |
|
100 }; |
|
101 |
|
102 #ifdef MOZ_CRASHREPORTER |
|
103 template<class Toplevel> |
|
104 inline bool |
|
105 CrashReporterParent::GeneratePairedMinidump(Toplevel* t) |
|
106 { |
|
107 CrashReporter::ProcessHandle child; |
|
108 #ifdef XP_MACOSX |
|
109 child = t->Process()->GetChildTask(); |
|
110 #else |
|
111 child = t->OtherProcess(); |
|
112 #endif |
|
113 nsCOMPtr<nsIFile> childDump; |
|
114 if (CrashReporter::CreatePairedMinidumps(child, |
|
115 mMainThread, |
|
116 getter_AddRefs(childDump)) && |
|
117 CrashReporter::GetIDFromMinidump(childDump, mChildDumpID)) { |
|
118 return true; |
|
119 } |
|
120 return false; |
|
121 } |
|
122 |
|
123 template<class Toplevel> |
|
124 inline bool |
|
125 CrashReporterParent::GenerateCrashReport(Toplevel* t, |
|
126 const AnnotationTable* processNotes) |
|
127 { |
|
128 nsCOMPtr<nsIFile> crashDump; |
|
129 if (t->TakeMinidump(getter_AddRefs(crashDump), nullptr) && |
|
130 CrashReporter::GetIDFromMinidump(crashDump, mChildDumpID)) { |
|
131 return GenerateChildData(processNotes); |
|
132 } |
|
133 return false; |
|
134 } |
|
135 |
|
136 template<class Toplevel> |
|
137 /* static */ bool |
|
138 CrashReporterParent::CreateCrashReporter(Toplevel* actor) |
|
139 { |
|
140 #ifdef MOZ_CRASHREPORTER |
|
141 NativeThreadId id; |
|
142 uint32_t processType; |
|
143 PCrashReporterParent* p = |
|
144 actor->CallPCrashReporterConstructor(&id, &processType); |
|
145 if (p) { |
|
146 static_cast<CrashReporterParent*>(p)->SetChildData(id, processType); |
|
147 } else { |
|
148 NS_ERROR("Error creating crash reporter actor"); |
|
149 } |
|
150 return !!p; |
|
151 #endif |
|
152 return false; |
|
153 } |
|
154 |
|
155 #endif |
|
156 |
|
157 } // namespace dom |
|
158 } // namespace mozilla |
|
159 |
|
160 #endif // mozilla_dom_CrashReporterParent_h |