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 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is Mozilla Plugin App.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * The Mozilla Foundation
20 : * Portions created by the Initial Developer are Copyright (C) 2010
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Ted Mielczarek <ted.mielczarek@gmail.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 : #include "mozilla/dom/PCrashReporterParent.h"
40 : #include "mozilla/dom/TabMessageUtils.h"
41 : #include "nsXULAppAPI.h"
42 : #include "nsILocalFile.h"
43 : #ifdef MOZ_CRASHREPORTER
44 : #include "nsExceptionHandler.h"
45 : #endif
46 :
47 : namespace mozilla {
48 : namespace dom {
49 : class ProcessReporter;
50 :
51 : class CrashReporterParent :
52 : public PCrashReporterParent
53 : {
54 : #ifdef MOZ_CRASHREPORTER
55 : typedef CrashReporter::AnnotationTable AnnotationTable;
56 : #endif
57 : public:
58 : CrashReporterParent();
59 : virtual ~CrashReporterParent();
60 :
61 : #ifdef MOZ_CRASHREPORTER
62 : /* Attempt to generate a parent/child pair of minidumps from the given
63 : toplevel actor in the event of a hang. Returns true if successful,
64 : false otherwise.
65 : */
66 : template<class Toplevel>
67 : bool
68 : GeneratePairedMinidump(Toplevel* t);
69 :
70 : /* Attempt to create a bare-bones crash report for a hang, along with extra
71 : process-specific annotations present in the given AnnotationTable. Returns
72 : true if successful, false otherwise.
73 : */
74 : bool
75 : GenerateHangCrashReport(const AnnotationTable* processNotes);
76 :
77 : /* Attempt to create a bare-bones crash report, along with extra process-
78 : specific annotations present in the given AnnotationTable. Returns true if
79 : successful, false otherwise.
80 : */
81 : template<class Toplevel>
82 : bool
83 : GenerateCrashReport(Toplevel* t, const AnnotationTable* processNotes);
84 :
85 : /* Instantiate a new crash reporter actor from a given parent that manages
86 : the protocol.
87 : */
88 : template<class Toplevel>
89 : static bool CreateCrashReporter(Toplevel* actor);
90 : #endif
91 : /* Initialize this reporter with data from the child process */
92 : void
93 : SetChildData(const NativeThreadId& id, const PRUint32& processType);
94 :
95 : /* Returns the shared hang ID of a parent/child paired minidump.
96 : GeneratePairedMinidump must be called first.
97 : */
98 0 : const nsString& HangID() {
99 0 : return mHangID;
100 : }
101 : /* Returns the ID of the parent minidump.
102 : GeneratePairedMinidump must be called first.
103 : */
104 0 : const nsString& ParentDumpID() {
105 0 : return mParentDumpID;
106 : }
107 : /* Returns the ID of the child minidump.
108 : GeneratePairedMinidump or GenerateCrashReport must be called first.
109 : */
110 0 : const nsString& ChildDumpID() {
111 0 : return mChildDumpID;
112 : }
113 :
114 : protected:
115 : virtual void ActorDestroy(ActorDestroyReason why);
116 :
117 : virtual bool
118 : RecvAddLibraryMappings(const InfallibleTArray<Mapping>& m);
119 : virtual bool
120 : RecvAnnotateCrashReport(const nsCString& key, const nsCString& data);
121 : virtual bool
122 : RecvAppendAppNotes(const nsCString& data);
123 :
124 : #ifdef MOZ_CRASHREPORTER
125 : bool
126 : GenerateChildData(const AnnotationTable* processNotes);
127 :
128 : AnnotationTable mNotes;
129 : #endif
130 : nsCString mAppNotes;
131 : nsString mHangID;
132 : nsString mChildDumpID;
133 : nsString mParentDumpID;
134 : NativeThreadId mMainThread;
135 : time_t mStartTime;
136 : PRUint32 mProcessType;
137 : bool mInitialized;
138 : };
139 :
140 : #ifdef MOZ_CRASHREPORTER
141 : template<class Toplevel>
142 : inline bool
143 0 : CrashReporterParent::GeneratePairedMinidump(Toplevel* t)
144 : {
145 : CrashReporter::ProcessHandle child;
146 : #ifdef XP_MACOSX
147 : child = t->Process()->GetChildTask();
148 : #else
149 0 : child = t->OtherProcess();
150 : #endif
151 0 : nsCOMPtr<nsILocalFile> childDump;
152 0 : nsCOMPtr<nsILocalFile> parentDump;
153 0 : if (CrashReporter::CreatePairedMinidumps(child,
154 : mMainThread,
155 : &mHangID,
156 : getter_AddRefs(childDump),
157 : getter_AddRefs(parentDump)) &&
158 : CrashReporter::GetIDFromMinidump(childDump, mChildDumpID) &&
159 : CrashReporter::GetIDFromMinidump(parentDump, mParentDumpID)) {
160 0 : return true;
161 : }
162 0 : return false;
163 : }
164 :
165 : template<class Toplevel>
166 : inline bool
167 0 : CrashReporterParent::GenerateCrashReport(Toplevel* t,
168 : const AnnotationTable* processNotes)
169 : {
170 0 : nsCOMPtr<nsILocalFile> crashDump;
171 0 : if (t->TakeMinidump(getter_AddRefs(crashDump)) &&
172 : CrashReporter::GetIDFromMinidump(crashDump, mChildDumpID)) {
173 0 : return GenerateChildData(processNotes);
174 : }
175 0 : return false;
176 : }
177 :
178 : template<class Toplevel>
179 : /* static */ bool
180 0 : CrashReporterParent::CreateCrashReporter(Toplevel* actor)
181 : {
182 : #ifdef MOZ_CRASHREPORTER
183 : NativeThreadId id;
184 : PRUint32 processType;
185 : PCrashReporterParent* p =
186 0 : actor->CallPCrashReporterConstructor(&id, &processType);
187 0 : if (p) {
188 0 : static_cast<CrashReporterParent*>(p)->SetChildData(id, processType);
189 : } else {
190 0 : NS_ERROR("Error creating crash reporter actor");
191 : }
192 0 : return !!p;
193 : #endif
194 : return false;
195 : }
196 :
197 : #endif
198 :
199 : } // namespace dom
200 : } // namespace mozilla
|