OLD | NEW |
1 // Copyright 2014 The Crashpad Authors. All rights reserved. | 1 // Copyright 2014 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include <stdint.h> | 22 #include <stdint.h> |
23 | 23 |
24 #include "base/files/file_path.h" | 24 #include "base/files/file_path.h" |
25 #include "base/macros.h" | 25 #include "base/macros.h" |
26 #include "build/build_config.h" | 26 #include "build/build_config.h" |
27 | 27 |
28 #if defined(OS_MACOSX) | 28 #if defined(OS_MACOSX) |
29 #include "base/mac/scoped_mach_port.h" | 29 #include "base/mac/scoped_mach_port.h" |
30 #elif defined(OS_WIN) | 30 #elif defined(OS_WIN) |
31 #include <windows.h> | 31 #include <windows.h> |
| 32 #include "util/win/scoped_handle.h" |
32 #endif | 33 #endif |
33 | 34 |
34 namespace crashpad { | 35 namespace crashpad { |
35 | 36 |
36 //! \brief The primary interface for an application to have Crashpad monitor | 37 //! \brief The primary interface for an application to have Crashpad monitor |
37 //! it for crashes. | 38 //! it for crashes. |
38 class CrashpadClient { | 39 class CrashpadClient { |
39 public: | 40 public: |
40 CrashpadClient(); | 41 CrashpadClient(); |
41 ~CrashpadClient(); | 42 ~CrashpadClient(); |
42 | 43 |
43 //! \brief Starts a Crashpad handler process, performing any necessary | 44 //! \brief Starts a Crashpad handler process, performing any necessary |
44 //! handshake to configure it. | 45 //! handshake to configure it. |
45 //! | 46 //! |
46 //! This method does not actually direct any crashes to the Crashpad handler, | 47 //! This method directs crashes to the Crashpad handler. On Mac OS X, this |
47 //! because there are alternative ways to use an existing Crashpad handler. To | 48 //! is applicable to this process and all child processes. On Windows, child |
48 //! begin directing crashes to the handler started by this method, call | 49 //! processes must also register by using SetHandlerIPCPipe(). |
49 //! UseHandler() after this method returns successfully. | |
50 //! | 50 //! |
51 //! On Mac OS X, this method starts a Crashpad handler and obtains a Mach | 51 //! On Mac OS X, this method starts a Crashpad handler and obtains a Mach send |
52 //! send right corresponding to a receive right held by the handler process. | 52 //! right corresponding to a receive right held by the handler process. The |
53 //! The handler process runs an exception server on this port. | 53 //! handler process runs an exception server on this port. This method sets |
| 54 //! the task’s exception port for `EXC_CRASH`, `EXC_RESOURCE`, and `EXC_GUARD` |
| 55 //! exceptions to the Mach send right obtained. The handler will be installed |
| 56 //! with behavior `EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES` and thread |
| 57 //! state flavor `MACHINE_THREAD_STATE`. Exception ports are inherited, so a |
| 58 //! Crashpad handler started here will remain the handler for any child |
| 59 //! processes created after StartHandler() is called. Child processes do not |
| 60 //! need to call StartHandler() or be aware of Crashpad in any way. The |
| 61 //! Crashpad handler will receive crashes from child processes that have |
| 62 //! inherited it as their exception handler even after the process that called |
| 63 //! StartHandler() exits. |
| 64 //! |
| 65 //! On Windows, if \a asynchronous_start is `true`, this function will not |
| 66 //! directly call `CreateProcess()`, making it suitable for use in a |
| 67 //! `DllMain()`. In that case, the handler is started from a background |
| 68 //! thread, deferring the handler's startup. Nevertheless, regardless of the |
| 69 //! value of \a asynchronous_start, after calling this method, the global |
| 70 //! unhandled exception filter is set up, and all crashes will be handled by |
| 71 //! Crashpad. Optionally, use WaitForHandlerStart() to join with the |
| 72 //! background thread and retrieve the status of handler startup. |
54 //! | 73 //! |
55 //! \param[in] handler The path to a Crashpad handler executable. | 74 //! \param[in] handler The path to a Crashpad handler executable. |
56 //! \param[in] database The path to a Crashpad database. The handler will be | 75 //! \param[in] database The path to a Crashpad database. The handler will be |
57 //! started with this path as its `--database` argument. | 76 //! started with this path as its `--database` argument. |
58 //! \param[in] metrics_dir The path to an already existing directory where | 77 //! \param[in] metrics_dir The path to an already existing directory where |
59 //! metrics files can be stored. The handler will be started with this | 78 //! metrics files can be stored. The handler will be started with this |
60 //! path as its `--metrics-dir` argument. | 79 //! path as its `--metrics-dir` argument. |
61 //! \param[in] url The URL of an upload server. The handler will be started | 80 //! \param[in] url The URL of an upload server. The handler will be started |
62 //! with this URL as its `--url` argument. | 81 //! with this URL as its `--url` argument. |
63 //! \param[in] annotations Process annotations to set in each crash report. | 82 //! \param[in] annotations Process annotations to set in each crash report. |
64 //! The handler will be started with an `--annotation` argument for each | 83 //! The handler will be started with an `--annotation` argument for each |
65 //! element in this map. | 84 //! element in this map. |
66 //! \param[in] arguments Additional arguments to pass to the Crashpad handler. | 85 //! \param[in] arguments Additional arguments to pass to the Crashpad handler. |
67 //! Arguments passed in other parameters and arguments required to perform | 86 //! Arguments passed in other parameters and arguments required to perform |
68 //! the handshake are the responsibility of this method, and must not be | 87 //! the handshake are the responsibility of this method, and must not be |
69 //! specified in this parameter. | 88 //! specified in this parameter. |
70 //! \param[in] restartable If `true`, the handler will be restarted if it | 89 //! \param[in] restartable If `true`, the handler will be restarted if it |
71 //! dies, if this behavior is supported. This option is not available on | 90 //! dies, if this behavior is supported. This option is not available on |
72 //! all platforms, and does not function on all OS versions. If it is | 91 //! all platforms, and does not function on all OS versions. If it is |
73 //! not supported, it will be ignored. | 92 //! not supported, it will be ignored. |
| 93 //! \param[out] asynchronous_start If `true`, the handler will be started from |
| 94 //! a background thread. Optionally, WaitForHandlerStart() can be used at |
| 95 //! a suitable time to retreive the result of background startup. This |
| 96 //! option is only used on Windows. |
74 //! | 97 //! |
75 //! \return `true` on success, `false` on failure with a message logged. | 98 //! \return `true` on success, `false` on failure with a message logged. |
76 bool StartHandler(const base::FilePath& handler, | 99 bool StartHandler(const base::FilePath& handler, |
77 const base::FilePath& database, | 100 const base::FilePath& database, |
78 const base::FilePath& metrics_dir, | 101 const base::FilePath& metrics_dir, |
79 const std::string& url, | 102 const std::string& url, |
80 const std::map<std::string, std::string>& annotations, | 103 const std::map<std::string, std::string>& annotations, |
81 const std::vector<std::string>& arguments, | 104 const std::vector<std::string>& arguments, |
82 bool restartable); | 105 bool restartable, |
| 106 bool asynchronous_start); |
83 | 107 |
84 #if defined(OS_MACOSX) || DOXYGEN | 108 #if defined(OS_MACOSX) || DOXYGEN |
85 //! \brief Sets the process’ crash handler to a Mach service registered with | 109 //! \brief Sets the process’ crash handler to a Mach service registered with |
86 //! the bootstrap server. | 110 //! the bootstrap server. |
87 //! | 111 //! |
88 //! This method does not actually direct any crashes to the Crashpad handler, | 112 //! This method is only defined on OS X. |
89 //! because there are alternative ways to start or use an existing Crashpad | |
90 //! handler. To begin directing crashes to the handler set by this method, | |
91 //! call UseHandler() after this method returns successfully. | |
92 //! | 113 //! |
93 //! This method is only defined on OS X. | 114 //! See StartHandler() for more detail on how the port and handler are |
| 115 //! configured. |
94 //! | 116 //! |
95 //! \param[in] service_name The service name of a Crashpad exception handler | 117 //! \param[in] service_name The service name of a Crashpad exception handler |
96 //! service previously registered with the bootstrap server. | 118 //! service previously registered with the bootstrap server. |
97 //! | 119 //! |
98 //! \return `true` on success, `false` on failure with a message logged. | 120 //! \return `true` on success, `false` on failure with a message logged. |
99 bool SetHandlerMachService(const std::string& service_name); | 121 bool SetHandlerMachService(const std::string& service_name); |
100 | 122 |
101 //! \brief Sets the process’ crash handler to a Mach port. | 123 //! \brief Sets the process’ crash handler to a Mach port. |
102 //! | 124 //! |
103 //! This method does not actually direct any crashes to the Crashpad handler, | 125 //! This method is only defined on OS X. |
104 //! because there are alternative ways to start or use an existing Crashpad | |
105 //! handler. To begin directing crashes to the handler set by this method, | |
106 //! call UseHandler() after this method. | |
107 //! | 126 //! |
108 //! This method is only defined on OS X. | 127 //! See StartHandler() for more detail on how the port and handler are |
| 128 //! configured. |
109 //! | 129 //! |
110 //! \param[in] exception_port An `exception_port_t` corresponding to a | 130 //! \param[in] exception_port An `exception_port_t` corresponding to a |
111 //! Crashpad exception handler service. | 131 //! Crashpad exception handler service. |
112 void SetHandlerMachPort(base::mac::ScopedMachSendRight exception_port); | 132 //! |
| 133 //! \return `true` on success, `false` on failure with a message logged. |
| 134 bool SetHandlerMachPort(base::mac::ScopedMachSendRight exception_port); |
113 #endif | 135 #endif |
114 | 136 |
115 #if defined(OS_WIN) || DOXYGEN | 137 #if defined(OS_WIN) || DOXYGEN |
116 //! \brief Sets the IPC pipe of a presumably-running Crashpad handler process | 138 //! \brief Sets the IPC pipe of a presumably-running Crashpad handler process |
117 //! which was started with StartHandler() or by other compatible means | 139 //! which was started with StartHandler() or by other compatible means |
118 //! and does an IPC message exchange to register this process with the | 140 //! and does an IPC message exchange to register this process with the |
119 //! handler. However, just like StartHandler(), crashes are not serviced | 141 //! handler. Crashes will be serviced once this method returns. |
120 //! until UseHandler() is called. | |
121 //! | 142 //! |
122 //! This method is only defined on Windows. | 143 //! This method is only defined on Windows. |
123 //! | 144 //! |
| 145 //! This method sets the unhandled exception handler to a local |
| 146 //! function that when reached will "signal and wait" for the crash handler |
| 147 //! process to create the dump. |
| 148 //! |
124 //! \param[in] ipc_pipe The full name of the crash handler IPC pipe. This is | 149 //! \param[in] ipc_pipe The full name of the crash handler IPC pipe. This is |
125 //! a string of the form `"\\.\pipe\NAME"`. | 150 //! a string of the form `"\\.\pipe\NAME"`. |
126 //! | 151 //! |
127 //! \return `true` on success and `false` on failure. | 152 //! \return `true` on success and `false` on failure. |
128 bool SetHandlerIPCPipe(const std::wstring& ipc_pipe); | 153 bool SetHandlerIPCPipe(const std::wstring& ipc_pipe); |
129 | 154 |
130 //! \brief Retrieves the IPC pipe name used to register with the Crashpad | 155 //! \brief Retrieves the IPC pipe name used to register with the Crashpad |
131 //! handler. | 156 //! handler. |
132 //! | 157 //! |
133 //! This method retrieves the IPC pipe name set by SetHandlerIPCPipe(), or a | 158 //! This method retrieves the IPC pipe name set by SetHandlerIPCPipe(), or a |
134 //! suitable IPC pipe name chosen by StartHandler(). It is intended to be used | 159 //! suitable IPC pipe name chosen by StartHandler(). It is intended to be used |
135 //! to obtain the IPC pipe name so that it may be passed to other processes, | 160 //! to obtain the IPC pipe name so that it may be passed to other processes, |
136 //! so that they may register with an existing Crashpad handler by calling | 161 //! so that they may register with an existing Crashpad handler by calling |
137 //! SetHandlerIPCPipe(). | 162 //! SetHandlerIPCPipe(). |
138 //! | 163 //! |
139 //! This method is only defined on Windows. | 164 //! This method is only defined on Windows. |
140 //! | 165 //! |
141 //! \return The full name of the crash handler IPC pipe, a string of the form | 166 //! \return The full name of the crash handler IPC pipe, a string of the form |
142 //! `"\\.\pipe\NAME"`. | 167 //! `"\\.\pipe\NAME"`. |
143 std::wstring GetHandlerIPCPipe() const; | 168 std::wstring GetHandlerIPCPipe() const; |
144 | 169 |
| 170 //! \brief When `asynchronous_start` is used with StartHandler(), this method |
| 171 //! can be used to block until the handler launch has been completed to |
| 172 //! retrieve status information. |
| 173 //! |
| 174 //! This method should not be used unless `asynchronous_start` was `true`. |
| 175 //! |
| 176 //! \return `true` if the hander startup succeeded, `false` otherwise, and an |
| 177 //! error message will have been logged. |
| 178 bool WaitForHandlerStart(); |
| 179 |
145 //! \brief Requests that the handler capture a dump even though there hasn't | 180 //! \brief Requests that the handler capture a dump even though there hasn't |
146 //! been a crash. | 181 //! been a crash. |
147 //! | 182 //! |
148 //! \param[in] context A `CONTEXT`, generally captured by CaptureContext() or | 183 //! \param[in] context A `CONTEXT`, generally captured by CaptureContext() or |
149 //! similar. | 184 //! similar. |
150 static void DumpWithoutCrash(const CONTEXT& context); | 185 static void DumpWithoutCrash(const CONTEXT& context); |
151 | 186 |
152 //! \brief Requests that the handler capture a dump using the given \a | 187 //! \brief Requests that the handler capture a dump using the given \a |
153 //! exception_pointers to get the `EXCEPTION_RECORD` and `CONTEXT`. | 188 //! exception_pointers to get the `EXCEPTION_RECORD` and `CONTEXT`. |
154 //! | 189 //! |
155 //! This function is not necessary in general usage as an unhandled exception | 190 //! This function is not necessary in general usage as an unhandled exception |
156 //! filter is installed by UseHandler(). | 191 //! filter is installed by StartHandler() or SetHandlerIPCPipe(). |
157 //! | 192 //! |
158 //! \param[in] exception_pointers An `EXCEPTION_POINTERS`, as would generally | 193 //! \param[in] exception_pointers An `EXCEPTION_POINTERS`, as would generally |
159 //! passed to an unhandled exception filter. | 194 //! passed to an unhandled exception filter. |
160 static void DumpAndCrash(EXCEPTION_POINTERS* exception_pointers); | 195 static void DumpAndCrash(EXCEPTION_POINTERS* exception_pointers); |
161 | 196 |
162 //! \brief Requests that the handler capture a dump of a different process. | 197 //! \brief Requests that the handler capture a dump of a different process. |
163 //! | 198 //! |
164 //! The target process must be an already-registered Crashpad client. An | 199 //! The target process must be an already-registered Crashpad client. An |
165 //! exception will be triggered in the target process, and the regular dump | 200 //! exception will be triggered in the target process, and the regular dump |
166 //! mechanism used. This function will block until the exception in the target | 201 //! mechanism used. This function will block until the exception in the target |
(...skipping 21 matching lines...) Expand all Loading... |
188 //! DumpAndCrashTargetProcess() triggers an exception in a target | 223 //! DumpAndCrashTargetProcess() triggers an exception in a target |
189 //! process. | 224 //! process. |
190 //! | 225 //! |
191 //! \note This value does not have any bits of the top nibble set, to avoid | 226 //! \note This value does not have any bits of the top nibble set, to avoid |
192 //! confusion with real exception codes which tend to have those bits | 227 //! confusion with real exception codes which tend to have those bits |
193 //! set. | 228 //! set. |
194 kTriggeredExceptionCode = 0xcca11ed, | 229 kTriggeredExceptionCode = 0xcca11ed, |
195 }; | 230 }; |
196 #endif | 231 #endif |
197 | 232 |
198 //! \brief Configures the process to direct its crashes to a Crashpad handler. | |
199 //! | |
200 //! The Crashpad handler must previously have been started by StartHandler() | |
201 //! or configured by SetHandlerMachService(), SetHandlerMachPort(), or | |
202 //! SetHandlerIPCPipe(). | |
203 //! | |
204 //! On Mac OS X, this method sets the task’s exception port for `EXC_CRASH`, | |
205 //! `EXC_RESOURCE`, and `EXC_GUARD` exceptions to the Mach send right obtained | |
206 //! by StartHandler(). The handler will be installed with behavior | |
207 //! `EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES` and thread state flavor | |
208 //! `MACHINE_THREAD_STATE`. Exception ports are inherited, so a Crashpad | |
209 //! handler chosen by UseHandler() will remain the handler for any child | |
210 //! processes created after UseHandler() is called. Child processes do not | |
211 //! need to call StartHandler() or UseHandler() or be aware of Crashpad in any | |
212 //! way. The Crashpad handler will receive crashes from child processes that | |
213 //! have inherited it as their exception handler even after the process that | |
214 //! called StartHandler() exits. | |
215 //! | |
216 //! On Windows, this method sets the unhandled exception handler to a local | |
217 //! function that when reached will "signal and wait" for the crash handler | |
218 //! process to create the dump. | |
219 //! | |
220 //! \return `true` on success, `false` on failure with a message logged. | |
221 bool UseHandler(); | |
222 | |
223 #if defined(OS_MACOSX) || DOXYGEN | 233 #if defined(OS_MACOSX) || DOXYGEN |
224 //! \brief Configures the process to direct its crashes to the default handler | 234 //! \brief Configures the process to direct its crashes to the default handler |
225 //! for the operating system. | 235 //! for the operating system. |
226 //! | 236 //! |
227 //! On OS X, this sets the task’s exception port as in UseHandler(), but the | 237 //! On OS X, this sets the task’s exception port as in SetHandlerMachPort(), |
228 //! exception handler used is obtained from SystemCrashReporterHandler(). If | 238 //! but the exception handler used is obtained from |
229 //! the system’s crash reporter handler cannot be determined or set, the | 239 //! SystemCrashReporterHandler(). If the system’s crash reporter handler |
230 //! task’s exception ports for crash-type exceptions are cleared. | 240 //! cannot be determined or set, the task’s exception ports for crash-type |
| 241 //! exceptions are cleared. |
231 //! | 242 //! |
232 //! Use of this function is strongly discouraged. | 243 //! Use of this function is strongly discouraged. |
233 //! | 244 //! |
234 //! \warning After a call to this function, Crashpad will no longer monitor | 245 //! \warning After a call to this function, Crashpad will no longer monitor |
235 //! the process for crashes until a subsequent call to UseHandler(). | 246 //! the process for crashes until a subsequent call to |
| 247 //! SetHandlerMachPort(). |
236 //! | 248 //! |
237 //! \note This is provided as a static function to allow it to be used in | 249 //! \note This is provided as a static function to allow it to be used in |
238 //! situations where a CrashpadClient object is not otherwise available. | 250 //! situations where a CrashpadClient object is not otherwise available. |
239 //! This may be useful when a child process inherits its parent’s Crashpad | 251 //! This may be useful when a child process inherits its parent’s Crashpad |
240 //! handler, but wants to sever this tie. | 252 //! handler, but wants to sever this tie. |
241 static void UseSystemDefaultHandler(); | 253 static void UseSystemDefaultHandler(); |
242 #endif | 254 #endif |
243 | 255 |
244 private: | 256 private: |
245 #if defined(OS_MACOSX) | 257 #if defined(OS_WIN) |
246 base::mac::ScopedMachSendRight exception_port_; | |
247 #elif defined(OS_WIN) | |
248 std::wstring ipc_pipe_; | 258 std::wstring ipc_pipe_; |
| 259 ScopedKernelHANDLE handler_start_thread_; |
249 #endif | 260 #endif |
250 | 261 |
251 DISALLOW_COPY_AND_ASSIGN(CrashpadClient); | 262 DISALLOW_COPY_AND_ASSIGN(CrashpadClient); |
252 }; | 263 }; |
253 | 264 |
254 } // namespace crashpad | 265 } // namespace crashpad |
255 | 266 |
256 #endif // CRASHPAD_CLIENT_CRASHPAD_CLIENT_H_ | 267 #endif // CRASHPAD_CLIENT_CRASHPAD_CLIENT_H_ |
OLD | NEW |