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"
18 #include "CrashAnnotations.h"
24 #include "nsXULAppAPI.h"
28 # ifdef WIN32_LEAN_AND_MEAN
29 # undef WIN32_LEAN_AND_MEAN
34 #if defined(XP_MACOSX)
35 # include <mach/mach.h>
44 namespace CrashReporter
{
47 * Returns true if the crash reporter is using the dummy implementation.
49 static inline bool IsDummy() {
50 #ifdef MOZ_CRASHREPORTER
57 nsresult
SetExceptionHandler(nsIFile
* aXREDirectory
, bool force
= false);
58 nsresult
UnsetExceptionHandler();
61 * Tell the crash reporter to recalculate where crash events files should go.
62 * SetCrashEventsDir is used before XPCOM is initialized from the startup
65 * UpdateCrashEventsDir uses the directory service to re-set the
66 * crash event directory based on the current profile.
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
73 void SetUserAppDataDirectory(nsIFile
* aDir
);
74 void SetProfileDirectory(nsIFile
* aDir
);
75 void UpdateCrashEventsDir();
76 void SetMemoryReportFile(nsIFile
* aFile
);
77 nsresult
GetDefaultMemoryReportFile(nsIFile
** aFile
);
80 * Get the path where crash event files should be written.
82 bool GetCrashEventsDir(nsAString
& aPath
);
85 bool GetServerURL(nsACString
& aServerURL
);
86 nsresult
SetServerURL(const nsACString
& aServerURL
);
87 bool GetMinidumpPath(nsAString
& aPath
);
88 nsresult
SetMinidumpPath(const nsAString
& aPath
);
90 // AnnotateCrashReport, RemoveCrashReportAnnotation and
91 // AppendAppNotesToCrashReport may be called from any thread in a chrome
92 // process, but may only be called from the main thread in a content process.
93 nsresult
AnnotateCrashReport(Annotation key
, bool data
);
94 nsresult
AnnotateCrashReport(Annotation key
, int data
);
95 nsresult
AnnotateCrashReport(Annotation key
, unsigned int data
);
96 nsresult
AnnotateCrashReport(Annotation key
, const nsACString
& data
);
97 nsresult
RemoveCrashReportAnnotation(Annotation key
);
98 nsresult
AppendAppNotesToCrashReport(const nsACString
& data
);
100 void AnnotateOOMAllocationSize(size_t size
);
101 void AnnotateTexturesSize(size_t size
);
102 nsresult
SetGarbageCollecting(bool collecting
);
103 void SetEventloopNestingLevel(uint32_t level
);
104 void SetMinidumpAnalysisAllThreads();
106 nsresult
SetRestartArgs(int argc
, char** argv
);
107 nsresult
SetupExtraData(nsIFile
* aAppDataDirectory
, const nsACString
& aBuildID
);
108 // Registers an additional memory region to be included in the minidump
109 nsresult
RegisterAppMemory(void* ptr
, size_t length
);
110 nsresult
UnregisterAppMemory(void* ptr
);
112 // Include heap regions of the crash context.
113 void SetIncludeContextHeap(bool aValue
);
115 void GetAnnotation(uint32_t childPid
, Annotation annotation
,
118 // Functions for working with minidumps and .extras
119 typedef mozilla::EnumeratedArray
<Annotation
, Annotation::Count
, nsCString
>
121 void DeleteMinidumpFilesForID(const nsAString
& id
);
122 bool GetMinidumpForID(const nsAString
& id
, nsIFile
** minidump
);
123 bool GetIDFromMinidump(nsIFile
* minidump
, nsAString
& id
);
124 bool GetExtraFileForID(const nsAString
& id
, nsIFile
** extraFile
);
125 bool GetExtraFileForMinidump(nsIFile
* minidump
, nsIFile
** extraFile
);
126 bool WriteExtraFile(const nsAString
& id
, const AnnotationTable
& annotations
);
129 * Copies the non-empty annotations in the source table to the destination
130 * overwriting the corresponding entries.
132 void MergeCrashAnnotations(AnnotationTable
& aDst
, const AnnotationTable
& aSrc
);
135 nsresult
WriteMinidumpForException(EXCEPTION_POINTERS
* aExceptionInfo
);
138 bool WriteMinidumpForSigInfo(int signo
, siginfo_t
* info
, void* uc
);
141 nsresult
AppendObjCExceptionInfoToAppNotes(void* inException
);
143 nsresult
GetSubmitReports(bool* aSubmitReport
);
144 nsresult
SetSubmitReports(bool aSubmitReport
);
146 // Out-of-process crash reporter API.
148 // Initializes out-of-process crash reporting. This method must be called
149 // before the platform-specific notification pipe APIs are called. If called
150 // from off the main thread, this method will synchronously proxy to the main
155 * Takes a minidump for the current process and returns the dump file.
156 * Callers are responsible for managing the resulting file.
158 * @param aResult - file pointer that holds the resulting minidump.
159 * @param aMoveToPending - if true move the report to the report
161 * @returns boolean indicating success or failure.
163 bool TakeMinidump(nsIFile
** aResult
, bool aMoveToPending
= false);
165 // Return true if a dump was found for |childPid|, and return the
166 // path in |dump|. The caller owns the last reference to |dump| if it
167 // is non-nullptr. The annotations for the crash will be stored in
168 // |aAnnotations|. The sequence parameter will be filled with an ordinal
169 // indicating which remote process crashed first.
170 bool TakeMinidumpForChild(uint32_t childPid
, nsIFile
** dump
,
171 AnnotationTable
& aAnnotations
,
172 uint32_t* aSequence
= nullptr);
175 * If a dump was found for |childPid| then write a minimal .extra file to
176 * complete it and remove it from the list of pending crash dumps. It's
177 * required to call this method after a non-main process crash if the crash
178 * report could not be finalized via the CrashReporterHost (for example because
179 * it wasn't instanced yet).
181 * @param aChildPid The pid of the crashed child process
182 * @param aType The type of the crashed process
183 * @param aDumpId A string that will be filled with the dump ID
185 [[nodiscard
]] bool FinalizeOrphanedMinidump(uint32_t aChildPid
,
186 GeckoProcessType aType
,
187 nsString
* aDumpId
= nullptr);
190 typedef HANDLE ProcessHandle
;
191 typedef DWORD ProcessId
;
192 typedef DWORD ThreadId
;
193 typedef HANDLE FileHandle
;
194 #elif defined(XP_MACOSX)
195 typedef task_t ProcessHandle
;
196 typedef pid_t ProcessId
;
197 typedef mach_port_t ThreadId
;
198 typedef int FileHandle
;
200 typedef int ProcessHandle
;
201 typedef pid_t ProcessId
;
202 typedef int ThreadId
;
203 typedef int FileHandle
;
207 int GetAnnotationTimeCrashFd();
209 void RegisterChildCrashAnnotationFileDescriptor(ProcessId aProcess
,
211 void DeregisterChildCrashAnnotationFileDescriptor(ProcessId aProcess
);
213 // Return the current thread's ID.
215 // XXX: this is a somewhat out-of-place interface to expose through
216 // crashreporter, but it takes significant work to call sys_gettid()
217 // correctly on Linux and breakpad has already jumped through those
219 ThreadId
CurrentThreadId();
222 * Take a minidump of the target process and pair it with an incoming minidump
223 * provided by the caller or a new minidump of the calling process and thread.
224 * The caller will own both dumps after this call. If this function fails
225 * it will attempt to delete any files that were created.
227 * The .extra information created will not include an 'additional_minidumps'
230 * @param aTargetPid The target process for the minidump.
231 * @param aTargetBlamedThread The target thread for the minidump.
232 * @param aIncomingPairName The name to apply to the paired dump the caller
234 * @param aIncomingDumpToPair Existing dump to pair with the new dump. if this
235 * is null, TakeMinidumpAndPair will take a new minidump of the calling
236 * process and thread and use it in aIncomingDumpToPairs place.
237 * @param aTargetDumpOut The target minidump file paired up with
238 * aIncomingDumpToPair.
239 * @param aTargetAnnotations The crash annotations of the target process.
240 * @return bool indicating success or failure
242 bool CreateMinidumpsAndPair(ProcessHandle aTargetPid
,
243 ThreadId aTargetBlamedThread
,
244 const nsACString
& aIncomingPairName
,
245 nsIFile
* aIncomingDumpToPair
,
246 AnnotationTable
& aTargetAnnotations
,
247 nsIFile
** aTargetDumpOut
);
249 // Create an additional minidump for a child of a process which already has
250 // a minidump (|parentMinidump|).
251 // The resulting dump will get the id of the parent and use the |name| as
253 bool CreateAdditionalChildMinidump(ProcessHandle childPid
,
254 ThreadId childBlamedThread
,
255 nsIFile
* parentMinidump
,
256 const nsACString
& name
);
258 #if defined(XP_WIN) || defined(XP_MACOSX)
259 // Parent-side API for children
260 const char* GetChildNotificationPipe();
262 # ifdef MOZ_CRASHREPORTER_INJECTOR
263 // Inject a crash report client into an arbitrary process, and inform the
264 // callback object when it crashes. Parent process only.
266 class InjectorCrashCallback
{
268 InjectorCrashCallback() {}
271 * Inform the callback of a crash. The client code should call
272 * TakeMinidumpForChild to remove it from the PID mapping table.
274 * The callback will not be fired if the client has already called
275 * TakeMinidumpForChild for this process ID.
277 virtual void OnCrash(DWORD processID
) = 0;
280 // This method implies OOPInit
281 void InjectCrashReporterIntoProcess(DWORD processID
, InjectorCrashCallback
* cb
);
282 void UnregisterInjectorCallback(DWORD processID
);
285 // Parent-side API for children
287 // Set the outparams for crash reporter server's fd (|childCrashFd|)
288 // and the magic fd number it should be remapped to
289 // (|childCrashRemapFd|) before exec() in the child process.
290 // |SetRemoteExceptionHandler()| in the child process expects to find
291 // the server at |childCrashRemapFd|. Return true iff successful.
293 // If crash reporting is disabled, both outparams will be set to -1
294 // and |true| will be returned.
295 bool CreateNotificationPipeForChild(int* childCrashFd
, int* childCrashRemapFd
);
300 bool SetRemoteExceptionHandler(const char* aCrashPipe
= nullptr,
301 uintptr_t aCrashTimeAnnotationFile
= 0);
302 bool UnsetRemoteExceptionHandler();
304 #if defined(MOZ_WIDGET_ANDROID)
305 // Android creates child process as services so we must explicitly set
306 // the handle for the pipe since it can't get remapped to a default value.
307 void SetNotificationPipeForChild(int childCrashFd
);
308 void SetCrashAnnotationPipeForChild(int childCrashAnnotationFd
);
310 // Android builds use a custom library loader, so /proc/<pid>/maps
311 // will just show anonymous mappings for all the non-system
312 // shared libraries. This API is to work around that by providing
313 // info about the shared libraries that are mapped into these anonymous
315 void AddLibraryMapping(const char* library_name
, uintptr_t start_address
,
316 size_t mapping_length
, size_t file_offset
);
320 // Annotates the crash report with the name of the calling thread.
321 void SetCurrentThreadName(const char* aName
);
323 } // namespace CrashReporter
325 #endif /* nsExceptionHandler_h__ */