Bug 1798711 - Remove duplication of DisableCrashReporter on gtest r=ahal
[gecko.git] / toolkit / crashreporter / nsExceptionHandler.h
blob08b0507520d5fb974d5759105437da412b370bcc
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/. */
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.
12 #ifndef nsExceptionHandler_h__
13 #define nsExceptionHandler_h__
15 #include "mozilla/Assertions.h"
16 #include "mozilla/EnumeratedArray.h"
17 #include "mozilla/Maybe.h"
19 #include "CrashAnnotations.h"
21 #include <stddef.h>
22 #include <stdint.h>
23 #include "nsError.h"
24 #include "nsString.h"
25 #include "nsXULAppAPI.h"
26 #include "prio.h"
28 #if defined(XP_WIN)
29 # ifdef WIN32_LEAN_AND_MEAN
30 # undef WIN32_LEAN_AND_MEAN
31 # endif
32 # include <windows.h>
33 #endif
35 #if defined(XP_MACOSX)
36 # include <mach/mach.h>
37 #endif
39 #if defined(XP_LINUX)
40 # include <signal.h>
41 #endif
43 class nsIFile;
45 namespace CrashReporter {
47 using mozilla::Maybe;
48 using mozilla::Nothing;
50 /**
51 * Returns true if the crash reporter is using the dummy implementation.
53 static inline bool IsDummy() {
54 #ifdef MOZ_CRASHREPORTER
55 return false;
56 #else
57 return true;
58 #endif
61 nsresult SetExceptionHandler(nsIFile* aXREDirectory, bool force = false);
62 nsresult UnsetExceptionHandler();
64 /**
65 * Tell the crash reporter to recalculate where crash events files should go.
66 * SetCrashEventsDir is used before XPCOM is initialized from the startup
67 * code.
69 * UpdateCrashEventsDir uses the directory service to re-set the
70 * crash event directory based on the current profile.
72 * 1. If environment variable is present, use it. We don't expect
73 * the environment variable except for tests and other atypical setups.
74 * 2. <profile>/crashes/events
75 * 3. <UAppData>/Crash Reports/events
77 void SetUserAppDataDirectory(nsIFile* aDir);
78 void SetProfileDirectory(nsIFile* aDir);
79 void UpdateCrashEventsDir();
80 void SetMemoryReportFile(nsIFile* aFile);
81 nsresult GetDefaultMemoryReportFile(nsIFile** aFile);
83 /**
84 * Get the path where crash event files should be written.
86 bool GetCrashEventsDir(nsAString& aPath);
88 bool GetEnabled();
89 bool GetServerURL(nsACString& aServerURL);
90 nsresult SetServerURL(const nsACString& aServerURL);
91 bool GetMinidumpPath(nsAString& aPath);
92 nsresult SetMinidumpPath(const nsAString& aPath);
94 // These functions are thread safe and can be called in both the parent and
95 // child processes. Annotations added in the main process will be included in
96 // child process crashes too unless the child process sets its own annotations.
97 // If it does the child-provided annotation overrides the one set in the parent.
98 nsresult AnnotateCrashReport(Annotation key, bool data);
99 nsresult AnnotateCrashReport(Annotation key, int data);
100 nsresult AnnotateCrashReport(Annotation key, unsigned int data);
101 nsresult AnnotateCrashReport(Annotation key, const nsACString& data);
102 nsresult AppendToCrashReportAnnotation(Annotation key, const nsACString& data);
103 nsresult RemoveCrashReportAnnotation(Annotation key);
104 nsresult AppendAppNotesToCrashReport(const nsACString& data);
106 // RAII class for setting a crash annotation during a limited scope of time.
107 // Will reset the named annotation to its previous value when destroyed.
109 // This type's behavior is identical to that of AnnotateCrashReport().
110 class MOZ_RAII AutoAnnotateCrashReport final {
111 public:
112 AutoAnnotateCrashReport(Annotation key, bool data);
113 AutoAnnotateCrashReport(Annotation key, int data);
114 AutoAnnotateCrashReport(Annotation key, unsigned int data);
115 AutoAnnotateCrashReport(Annotation key, const nsACString& data);
116 ~AutoAnnotateCrashReport();
118 #ifdef MOZ_CRASHREPORTER
119 private:
120 Annotation mKey;
121 nsCString mPrevious;
122 #endif
125 void AnnotateOOMAllocationSize(size_t size);
126 void AnnotateTexturesSize(size_t size);
127 nsresult SetGarbageCollecting(bool collecting);
128 void SetEventloopNestingLevel(uint32_t level);
129 void SetMinidumpAnalysisAllThreads();
130 void ClearInactiveStateStart();
131 void SetInactiveStateStart();
133 nsresult SetRestartArgs(int argc, char** argv);
134 nsresult SetupExtraData(nsIFile* aAppDataDirectory, const nsACString& aBuildID);
135 // Registers an additional memory region to be included in the minidump
136 nsresult RegisterAppMemory(void* ptr, size_t length);
137 nsresult UnregisterAppMemory(void* ptr);
139 // Include heap regions of the crash context.
140 void SetIncludeContextHeap(bool aValue);
142 void GetAnnotation(uint32_t childPid, Annotation annotation,
143 nsACString& outStr);
145 // Functions for working with minidumps and .extras
146 typedef mozilla::EnumeratedArray<Annotation, Annotation::Count, nsCString>
147 AnnotationTable;
148 void DeleteMinidumpFilesForID(
149 const nsAString& aId,
150 const Maybe<nsString>& aAdditionalMinidump = Nothing());
151 bool GetMinidumpForID(const nsAString& id, nsIFile** minidump,
152 const Maybe<nsString>& aAdditionalMinidump = Nothing());
153 bool GetIDFromMinidump(nsIFile* minidump, nsAString& id);
154 bool GetExtraFileForID(const nsAString& id, nsIFile** extraFile);
155 bool GetExtraFileForMinidump(nsIFile* minidump, nsIFile** extraFile);
156 bool WriteExtraFile(const nsAString& id, const AnnotationTable& annotations);
159 * Copies the non-empty annotations in the source table to the destination
160 * overwriting the corresponding entries.
162 void MergeCrashAnnotations(AnnotationTable& aDst, const AnnotationTable& aSrc);
164 #ifdef XP_WIN
165 nsresult WriteMinidumpForException(EXCEPTION_POINTERS* aExceptionInfo);
166 #endif
167 #ifdef XP_LINUX
168 bool WriteMinidumpForSigInfo(int signo, siginfo_t* info, void* uc);
169 #endif
170 #ifdef XP_MACOSX
171 nsresult AppendObjCExceptionInfoToAppNotes(void* inException);
172 #endif
173 nsresult GetSubmitReports(bool* aSubmitReport);
174 nsresult SetSubmitReports(bool aSubmitReport);
176 // Out-of-process crash reporter API.
178 #ifdef XP_WIN
179 // This data is stored in the parent process, there is one copy for each child
180 // process. The mChildPid and mMinidumpFile fields are filled by the WER runtime
181 // exception module when the associated child process crashes.
182 struct WindowsErrorReportingData {
183 // Points to the WerNotifyProc function.
184 LPTHREAD_START_ROUTINE mWerNotifyProc;
185 // PID of the child process that crashed.
186 DWORD mChildPid;
187 // Filename of the generated minidump; this is not a 0-terminated string
188 char mMinidumpFile[40];
189 // OOM allocation size for the crash (ignore if zero)
190 size_t mOOMAllocationSize;
192 #endif // XP_WIN
194 // Initializes out-of-process crash reporting. This method must be called
195 // before the platform-specific notification pipe APIs are called. If called
196 // from off the main thread, this method will synchronously proxy to the main
197 // thread.
198 void OOPInit();
200 // Return true if a dump was found for |childPid|, and return the
201 // path in |dump|. The caller owns the last reference to |dump| if it
202 // is non-nullptr. The annotations for the crash will be stored in
203 // |aAnnotations|. The sequence parameter will be filled with an ordinal
204 // indicating which remote process crashed first.
205 bool TakeMinidumpForChild(uint32_t childPid, nsIFile** dump,
206 AnnotationTable& aAnnotations,
207 uint32_t* aSequence = nullptr);
210 * If a dump was found for |childPid| then write a minimal .extra file to
211 * complete it and remove it from the list of pending crash dumps. It's
212 * required to call this method after a non-main process crash if the crash
213 * report could not be finalized via the CrashReporterHost (for example because
214 * it wasn't instanced yet).
216 * @param aChildPid The pid of the crashed child process
217 * @param aType The type of the crashed process
218 * @param aDumpId A string that will be filled with the dump ID
220 [[nodiscard]] bool FinalizeOrphanedMinidump(uint32_t aChildPid,
221 GeckoProcessType aType,
222 nsString* aDumpId = nullptr);
224 #if defined(XP_WIN)
225 typedef HANDLE ProcessHandle;
226 typedef DWORD ProcessId;
227 typedef DWORD ThreadId;
228 typedef HANDLE FileHandle;
229 const FileHandle kInvalidFileHandle = INVALID_HANDLE_VALUE;
230 #elif defined(XP_MACOSX)
231 typedef task_t ProcessHandle;
232 typedef pid_t ProcessId;
233 typedef mach_port_t ThreadId;
234 typedef int FileHandle;
235 const FileHandle kInvalidFileHandle = -1;
236 #else
237 typedef int ProcessHandle;
238 typedef pid_t ProcessId;
239 typedef int ThreadId;
240 typedef int FileHandle;
241 const FileHandle kInvalidFileHandle = -1;
242 #endif
244 #if !defined(XP_WIN)
245 FileHandle GetAnnotationTimeCrashFd();
246 #endif
247 void RegisterChildCrashAnnotationFileDescriptor(ProcessId aProcess,
248 PRFileDesc* aFd);
249 void DeregisterChildCrashAnnotationFileDescriptor(ProcessId aProcess);
251 // Return the current thread's ID.
253 // XXX: this is a somewhat out-of-place interface to expose through
254 // crashreporter, but it takes significant work to call sys_gettid()
255 // correctly on Linux and breakpad has already jumped through those
256 // hoops for us.
257 ThreadId CurrentThreadId();
260 * Take a minidump of the target process and pair it with a new minidump of the
261 * calling process and thread. The caller will own both dumps after this call.
262 * If this function fails it will attempt to delete any files that were created.
264 * The .extra information created will not include an 'additional_minidumps'
265 * annotation.
267 * @param aTargetPid The target process for the minidump.
268 * @param aTargetBlamedThread The target thread for the minidump.
269 * @param aIncomingPairName The name to apply to the paired dump the caller
270 * passes in.
271 * @param aTargetDumpOut The target minidump file paired up with the new one.
272 * @param aTargetAnnotations The crash annotations of the target process.
273 * @return bool indicating success or failure
275 bool CreateMinidumpsAndPair(ProcessHandle aTargetPid,
276 ThreadId aTargetBlamedThread,
277 const nsACString& aIncomingPairName,
278 AnnotationTable& aTargetAnnotations,
279 nsIFile** aTargetDumpOut);
281 #if defined(XP_WIN) || defined(XP_MACOSX)
282 // Parent-side API for children
283 const char* GetChildNotificationPipe();
285 # ifdef MOZ_CRASHREPORTER_INJECTOR
286 // Inject a crash report client into an arbitrary process, and inform the
287 // callback object when it crashes. Parent process only.
289 class InjectorCrashCallback {
290 public:
291 InjectorCrashCallback() {}
294 * Inform the callback of a crash. The client code should call
295 * TakeMinidumpForChild to remove it from the PID mapping table.
297 * The callback will not be fired if the client has already called
298 * TakeMinidumpForChild for this process ID.
300 virtual void OnCrash(DWORD processID) = 0;
303 // This method implies OOPInit
304 void InjectCrashReporterIntoProcess(DWORD processID, InjectorCrashCallback* cb);
305 void UnregisterInjectorCallback(DWORD processID);
306 # endif
307 #else
308 // Parent-side API for children
310 // Set the outparams for crash reporter server's fd (|childCrashFd|)
311 // and the magic fd number it should be remapped to
312 // (|childCrashRemapFd|) before exec() in the child process.
313 // |SetRemoteExceptionHandler()| in the child process expects to find
314 // the server at |childCrashRemapFd|. Return true if successful.
316 // If crash reporting is disabled, both outparams will be set to -1
317 // and |true| will be returned.
318 bool CreateNotificationPipeForChild(int* childCrashFd, int* childCrashRemapFd);
320 #endif // XP_WIN
322 // Windows Error Reporting helper
323 #if defined(XP_WIN)
324 DWORD WINAPI WerNotifyProc(LPVOID aParameter);
325 #endif
327 // Child-side API
328 bool SetRemoteExceptionHandler(
329 const char* aCrashPipe = nullptr,
330 FileHandle aCrashTimeAnnotationFile = kInvalidFileHandle);
331 bool UnsetRemoteExceptionHandler();
333 #if defined(MOZ_WIDGET_ANDROID)
334 // Android creates child process as services so we must explicitly set
335 // the handle for the pipe since it can't get remapped to a default value.
336 void SetNotificationPipeForChild(FileHandle childCrashFd);
337 void SetCrashAnnotationPipeForChild(FileHandle childCrashAnnotationFd);
338 #endif
340 } // namespace CrashReporter
342 #endif /* nsExceptionHandler_h__ */