/src/mozilla-central/toolkit/crashreporter/nsExceptionHandler.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | // This header has two implementations, the real one in nsExceptionHandler.cpp |
7 | | // and a dummy in nsDummyExceptionHandler.cpp. The latter is used in builds |
8 | | // configured with --disable-crashreporter. If you add or remove a function |
9 | | // from this header you must update both implementations otherwise you'll break |
10 | | // builds that disable the crash reporter. |
11 | | |
12 | | #ifndef nsExceptionHandler_h__ |
13 | | #define nsExceptionHandler_h__ |
14 | | |
15 | | #include "mozilla/Assertions.h" |
16 | | #include "mozilla/EnumeratedArray.h" |
17 | | |
18 | | #include "CrashAnnotations.h" |
19 | | |
20 | | #include <stddef.h> |
21 | | #include <stdint.h> |
22 | | #include "nsError.h" |
23 | | #include "nsString.h" |
24 | | #include "prio.h" |
25 | | |
26 | | #if defined(XP_WIN32) |
27 | | #ifdef WIN32_LEAN_AND_MEAN |
28 | | #undef WIN32_LEAN_AND_MEAN |
29 | | #endif |
30 | | #include <windows.h> |
31 | | #endif |
32 | | |
33 | | #if defined(XP_MACOSX) |
34 | | #include <mach/mach.h> |
35 | | #endif |
36 | | |
37 | | #if defined(XP_LINUX) |
38 | | #include <signal.h> |
39 | | #endif |
40 | | |
41 | | class nsIFile; |
42 | | |
43 | | namespace CrashReporter { |
44 | | |
45 | | /** |
46 | | * Returns true if the crash reporter is using the dummy implementation. |
47 | | */ |
48 | | static inline bool |
49 | 0 | IsDummy() { |
50 | | #ifdef MOZ_CRASHREPORTER |
51 | | return false; |
52 | | #else |
53 | | return true; |
54 | 0 | #endif |
55 | 0 | } Unexecuted instantiation: BackgroundChildImpl.cpp:CrashReporter::IsDummy() Unexecuted instantiation: BackgroundParentImpl.cpp:CrashReporter::IsDummy() Unexecuted instantiation: FileDescriptorSetChild.cpp:CrashReporter::IsDummy() Unexecuted instantiation: FileDescriptorSetParent.cpp:CrashReporter::IsDummy() Unexecuted instantiation: Unified_cpp_ipc_glue0.cpp:CrashReporter::IsDummy() Unexecuted instantiation: Unified_cpp_ipc_glue1.cpp:CrashReporter::IsDummy() Unexecuted instantiation: GPUParent.cpp:CrashReporter::IsDummy() Unexecuted instantiation: Unified_cpp_gfx_ipc0.cpp:CrashReporter::IsDummy() Unexecuted instantiation: ContentChild.cpp:CrashReporter::IsDummy() Unexecuted instantiation: ProcessHangMonitor.cpp:CrashReporter::IsDummy() Unexecuted instantiation: Unified_cpp_dom_ipc0.cpp:CrashReporter::IsDummy() Unexecuted instantiation: Unified_cpp_dom_ipc1.cpp:CrashReporter::IsDummy() Unexecuted instantiation: Unified_cpp_crashreporter0.cpp:CrashReporter::IsDummy() Unexecuted instantiation: nsAppRunner.cpp:CrashReporter::IsDummy() Unexecuted instantiation: nsEmbedFunctions.cpp:CrashReporter::IsDummy() Unexecuted instantiation: Unified_cpp_toolkit_xre0.cpp:CrashReporter::IsDummy() |
56 | | |
57 | | nsresult SetExceptionHandler(nsIFile* aXREDirectory, bool force=false); |
58 | | nsresult UnsetExceptionHandler(); |
59 | | |
60 | | /** |
61 | | * Tell the crash reporter to recalculate where crash events files should go. |
62 | | * SetCrashEventsDir is used before XPCOM is initialized from the startup |
63 | | * code. |
64 | | * |
65 | | * UpdateCrashEventsDir uses the directory service to re-set the |
66 | | * crash event directory based on the current profile. |
67 | | * |
68 | | * 1. If environment variable is present, use it. We don't expect |
69 | | * the environment variable except for tests and other atypical setups. |
70 | | * 2. <profile>/crashes/events |
71 | | * 3. <UAppData>/Crash Reports/events |
72 | | */ |
73 | | void SetUserAppDataDirectory(nsIFile* aDir); |
74 | | void SetProfileDirectory(nsIFile* aDir); |
75 | | void UpdateCrashEventsDir(); |
76 | | void SetMemoryReportFile(nsIFile* aFile); |
77 | | nsresult GetDefaultMemoryReportFile(nsIFile** aFile); |
78 | | void SetTelemetrySessionId(const nsACString& id); |
79 | | |
80 | | /** |
81 | | * Get the path where crash event files should be written. |
82 | | */ |
83 | | bool GetCrashEventsDir(nsAString& aPath); |
84 | | |
85 | | bool GetEnabled(); |
86 | | bool GetServerURL(nsACString& aServerURL); |
87 | | nsresult SetServerURL(const nsACString& aServerURL); |
88 | | bool GetMinidumpPath(nsAString& aPath); |
89 | | nsresult SetMinidumpPath(const nsAString& aPath); |
90 | | |
91 | | |
92 | | // AnnotateCrashReport, RemoveCrashReportAnnotation and |
93 | | // AppendAppNotesToCrashReport may be called from any thread in a chrome |
94 | | // process, but may only be called from the main thread in a content process. |
95 | | nsresult AnnotateCrashReport(Annotation key, bool data); |
96 | | nsresult AnnotateCrashReport(Annotation key, int data); |
97 | | nsresult AnnotateCrashReport(Annotation key, unsigned int data); |
98 | | nsresult AnnotateCrashReport(Annotation key, const nsACString& data); |
99 | | nsresult RemoveCrashReportAnnotation(Annotation key); |
100 | | nsresult AppendAppNotesToCrashReport(const nsACString& data); |
101 | | |
102 | | // Called after the crash reporter client has been created in a content |
103 | | // process, allowing annotations to be processed. |
104 | | void NotifyCrashReporterClientCreated(); |
105 | | |
106 | | void AnnotateOOMAllocationSize(size_t size); |
107 | | void AnnotateTexturesSize(size_t size); |
108 | | nsresult SetGarbageCollecting(bool collecting); |
109 | | void SetEventloopNestingLevel(uint32_t level); |
110 | | void SetMinidumpAnalysisAllThreads(); |
111 | | |
112 | | nsresult SetRestartArgs(int argc, char** argv); |
113 | | nsresult SetupExtraData(nsIFile* aAppDataDirectory, |
114 | | const nsACString& aBuildID); |
115 | | // Registers an additional memory region to be included in the minidump |
116 | | nsresult RegisterAppMemory(void* ptr, size_t length); |
117 | | nsresult UnregisterAppMemory(void* ptr); |
118 | | |
119 | | // Include heap regions of the crash context. |
120 | | void SetIncludeContextHeap(bool aValue); |
121 | | |
122 | | // Functions for working with minidumps and .extras |
123 | | typedef mozilla::EnumeratedArray<Annotation, Annotation::Count, nsCString> |
124 | | AnnotationTable; |
125 | | |
126 | | void DeleteMinidumpFilesForID(const nsAString& id); |
127 | | bool GetMinidumpForID(const nsAString& id, nsIFile** minidump); |
128 | | bool GetIDFromMinidump(nsIFile* minidump, nsAString& id); |
129 | | bool GetExtraFileForID(const nsAString& id, nsIFile** extraFile); |
130 | | bool GetExtraFileForMinidump(nsIFile* minidump, nsIFile** extraFile); |
131 | | bool AppendExtraData(const nsAString& id, const AnnotationTable& data); |
132 | | bool AppendExtraData(nsIFile* extraFile, const AnnotationTable& data); |
133 | | |
134 | | /* |
135 | | * Renames the stand alone dump file aDumpFile to: |
136 | | * |aOwnerDumpFile-aDumpFileProcessType.dmp| |
137 | | * and moves it into the same directory as aOwnerDumpFile. Does not |
138 | | * modify aOwnerDumpFile in any way. |
139 | | * |
140 | | * @param aDumpFile - the dump file to associate with aOwnerDumpFile. |
141 | | * @param aOwnerDumpFile - the new owner of aDumpFile. |
142 | | * @param aDumpFileProcessType - process name associated with aDumpFile. |
143 | | */ |
144 | | void RenameAdditionalHangMinidump(nsIFile* aDumpFile, const nsIFile* aOwnerDumpFile, |
145 | | const nsACString& aDumpFileProcessType); |
146 | | |
147 | | #ifdef XP_WIN32 |
148 | | nsresult WriteMinidumpForException(EXCEPTION_POINTERS* aExceptionInfo); |
149 | | #endif |
150 | | #ifdef XP_LINUX |
151 | | bool WriteMinidumpForSigInfo(int signo, siginfo_t* info, void* uc); |
152 | | #endif |
153 | | #ifdef XP_MACOSX |
154 | | nsresult AppendObjCExceptionInfoToAppNotes(void *inException); |
155 | | #endif |
156 | | nsresult GetSubmitReports(bool* aSubmitReport); |
157 | | nsresult SetSubmitReports(bool aSubmitReport); |
158 | | |
159 | | // Out-of-process crash reporter API. |
160 | | |
161 | | // Initializes out-of-process crash reporting. This method must be called |
162 | | // before the platform-specific notification pipe APIs are called. If called |
163 | | // from off the main thread, this method will synchronously proxy to the main |
164 | | // thread. |
165 | | void OOPInit(); |
166 | | |
167 | | /* |
168 | | * Takes a minidump for the current process and returns the dump file. |
169 | | * Callers are responsible for managing the resulting file. |
170 | | * |
171 | | * @param aResult - file pointer that holds the resulting minidump. |
172 | | * @param aMoveToPending - if true move the report to the report |
173 | | * pending directory. |
174 | | * @returns boolean indicating success or failure. |
175 | | */ |
176 | | bool TakeMinidump(nsIFile** aResult, bool aMoveToPending = false); |
177 | | |
178 | | // Return true if a dump was found for |childPid|, and return the |
179 | | // path in |dump|. The caller owns the last reference to |dump| if it |
180 | | // is non-nullptr. The sequence parameter will be filled with an ordinal |
181 | | // indicating which remote process crashed first. |
182 | | bool TakeMinidumpForChild(uint32_t childPid, |
183 | | nsIFile** dump, |
184 | | uint32_t* aSequence = nullptr); |
185 | | |
186 | | #if defined(XP_WIN) |
187 | | typedef HANDLE ProcessHandle; |
188 | | typedef DWORD ProcessId; |
189 | | typedef DWORD ThreadId; |
190 | | typedef HANDLE FileHandle; |
191 | | #elif defined(XP_MACOSX) |
192 | | typedef task_t ProcessHandle; |
193 | | typedef pid_t ProcessId; |
194 | | typedef mach_port_t ThreadId; |
195 | | typedef int FileHandle; |
196 | | #else |
197 | | typedef int ProcessHandle; |
198 | | typedef pid_t ProcessId; |
199 | | typedef int ThreadId; |
200 | | typedef int FileHandle; |
201 | | #endif |
202 | | |
203 | | #if !defined(XP_WIN) |
204 | | int |
205 | | GetAnnotationTimeCrashFd(); |
206 | | #endif |
207 | | void |
208 | | RegisterChildCrashAnnotationFileDescriptor(ProcessId aProcess, PRFileDesc* aFd); |
209 | | void |
210 | | DeregisterChildCrashAnnotationFileDescriptor(ProcessId aProcess); |
211 | | |
212 | | // Return the current thread's ID. |
213 | | // |
214 | | // XXX: this is a somewhat out-of-place interface to expose through |
215 | | // crashreporter, but it takes significant work to call sys_gettid() |
216 | | // correctly on Linux and breakpad has already jumped through those |
217 | | // hoops for us. |
218 | | ThreadId CurrentThreadId(); |
219 | | |
220 | | /* |
221 | | * Take a minidump of the target process and pair it with an incoming minidump |
222 | | * provided by the caller or a new minidump of the calling process and thread. |
223 | | * The caller will own both dumps after this call. If this function fails |
224 | | * it will attempt to delete any files that were created. |
225 | | * |
226 | | * The .extra information created will not include an 'additional_minidumps' |
227 | | * annotation. |
228 | | * |
229 | | * @param aTargetPid The target process for the minidump. |
230 | | * @param aTargetBlamedThread The target thread for the minidump. |
231 | | * @param aIncomingPairName The name to apply to the paired dump the caller |
232 | | * passes in. |
233 | | * @param aIncomingDumpToPair Existing dump to pair with the new dump. if this |
234 | | * is null, TakeMinidumpAndPair will take a new minidump of the calling |
235 | | * process and thread and use it in aIncomingDumpToPairs place. |
236 | | * @param aTargetDumpOut The target minidump file paired up with |
237 | | * aIncomingDumpToPair. |
238 | | * @return bool indicating success or failure |
239 | | */ |
240 | | bool CreateMinidumpsAndPair(ProcessHandle aTargetPid, |
241 | | ThreadId aTargetBlamedThread, |
242 | | const nsACString& aIncomingPairName, |
243 | | nsIFile* aIncomingDumpToPair, |
244 | | nsIFile** aTargetDumpOut); |
245 | | |
246 | | // Create an additional minidump for a child of a process which already has |
247 | | // a minidump (|parentMinidump|). |
248 | | // The resulting dump will get the id of the parent and use the |name| as |
249 | | // an extension. |
250 | | bool CreateAdditionalChildMinidump(ProcessHandle childPid, |
251 | | ThreadId childBlamedThread, |
252 | | nsIFile* parentMinidump, |
253 | | const nsACString& name); |
254 | | |
255 | | // Parent-side API, returns the tmp dir for child processes to use, accounting |
256 | | // for sandbox considerations. |
257 | | void GetChildProcessTmpDir(nsIFile** aOutTmpDir); |
258 | | |
259 | | # if defined(XP_WIN32) || defined(XP_MACOSX) |
260 | | // Parent-side API for children |
261 | | const char* GetChildNotificationPipe(); |
262 | | |
263 | | #ifdef MOZ_CRASHREPORTER_INJECTOR |
264 | | // Inject a crash report client into an arbitrary process, and inform the |
265 | | // callback object when it crashes. Parent process only. |
266 | | |
267 | | class InjectorCrashCallback |
268 | | { |
269 | | public: |
270 | | InjectorCrashCallback() { } |
271 | | |
272 | | /** |
273 | | * Inform the callback of a crash. The client code should call |
274 | | * TakeMinidumpForChild to remove it from the PID mapping table. |
275 | | * |
276 | | * The callback will not be fired if the client has already called |
277 | | * TakeMinidumpForChild for this process ID. |
278 | | */ |
279 | | virtual void OnCrash(DWORD processID) = 0; |
280 | | }; |
281 | | |
282 | | // This method implies OOPInit |
283 | | void InjectCrashReporterIntoProcess(DWORD processID, InjectorCrashCallback* cb); |
284 | | void UnregisterInjectorCallback(DWORD processID); |
285 | | #endif |
286 | | |
287 | | // Child-side API |
288 | | #if defined(XP_WIN32) |
289 | | bool |
290 | | SetRemoteExceptionHandler(const nsACString& crashPipe, |
291 | | uintptr_t aCrashTimeAnnotationFile); |
292 | | #else |
293 | | bool SetRemoteExceptionHandler(const nsACString& crashPipe); |
294 | | #endif |
295 | | |
296 | | # else |
297 | | // Parent-side API for children |
298 | | |
299 | | // Set the outparams for crash reporter server's fd (|childCrashFd|) |
300 | | // and the magic fd number it should be remapped to |
301 | | // (|childCrashRemapFd|) before exec() in the child process. |
302 | | // |SetRemoteExceptionHandler()| in the child process expects to find |
303 | | // the server at |childCrashRemapFd|. Return true iff successful. |
304 | | // |
305 | | // If crash reporting is disabled, both outparams will be set to -1 |
306 | | // and |true| will be returned. |
307 | | bool CreateNotificationPipeForChild(int* childCrashFd, int* childCrashRemapFd); |
308 | | |
309 | | // Child-side API |
310 | | bool SetRemoteExceptionHandler(); |
311 | | |
312 | | #endif // XP_WIN32 |
313 | | |
314 | | bool UnsetRemoteExceptionHandler(); |
315 | | |
316 | | #if defined(MOZ_WIDGET_ANDROID) |
317 | | // Android creates child process as services so we must explicitly set |
318 | | // the handle for the pipe since it can't get remapped to a default value. |
319 | | void SetNotificationPipeForChild(int childCrashFd); |
320 | | void SetCrashAnnotationPipeForChild(int childCrashAnnotationFd); |
321 | | |
322 | | // Android builds use a custom library loader, so /proc/<pid>/maps |
323 | | // will just show anonymous mappings for all the non-system |
324 | | // shared libraries. This API is to work around that by providing |
325 | | // info about the shared libraries that are mapped into these anonymous |
326 | | // mappings. |
327 | | void AddLibraryMapping(const char* library_name, |
328 | | uintptr_t start_address, |
329 | | size_t mapping_length, |
330 | | size_t file_offset); |
331 | | |
332 | | #endif |
333 | | |
334 | | // Annotates the crash report with the name of the calling thread. |
335 | | void SetCurrentThreadName(const char* aName); |
336 | | |
337 | | } // namespace CrashReporter |
338 | | |
339 | | #endif /* nsExceptionHandler_h__ */ |