OLD | NEW |
1 // Copyright (c) 2010 Google Inc. | 1 // Copyright (c) 2010 Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 // Before writing a minidump, the optional |filter| callback will be called. | 117 // Before writing a minidump, the optional |filter| callback will be called. |
118 // Its return value determines whether or not Breakpad should write a | 118 // Its return value determines whether or not Breakpad should write a |
119 // minidump. The minidump content will be written to the file path or file | 119 // minidump. The minidump content will be written to the file path or file |
120 // descriptor from |descriptor|, and the optional |callback| is called after | 120 // descriptor from |descriptor|, and the optional |callback| is called after |
121 // writing the dump file, as described above. | 121 // writing the dump file, as described above. |
122 // If install_handler is true, then a minidump will be written whenever | 122 // If install_handler is true, then a minidump will be written whenever |
123 // an unhandled exception occurs. If it is false, minidumps will only | 123 // an unhandled exception occurs. If it is false, minidumps will only |
124 // be written when WriteMinidump is called. | 124 // be written when WriteMinidump is called. |
125 // If |server_fd| is valid, the minidump is generated out-of-process. If it | 125 // If |server_fd| is valid, the minidump is generated out-of-process. If it |
126 // is -1, in-process generation will always be used. | 126 // is -1, in-process generation will always be used. |
| 127 // |flags| control what gets written to the minidump file and defaults to |
| 128 // DUMP_ALL |
127 ExceptionHandler(const MinidumpDescriptor& descriptor, | 129 ExceptionHandler(const MinidumpDescriptor& descriptor, |
128 FilterCallback filter, | 130 FilterCallback filter, |
129 MinidumpCallback callback, | 131 MinidumpCallback callback, |
130 void* callback_context, | 132 void* callback_context, |
131 bool install_handler, | 133 bool install_handler, |
132 const int server_fd); | 134 const int server_fd); |
| 135 ExceptionHandler(const MinidumpDescriptor& descriptor, |
| 136 FilterCallback filter, |
| 137 MinidumpCallback callback, |
| 138 void* callback_context, |
| 139 bool install_handler, |
| 140 const int server_fd, |
| 141 ContentFlags flags); |
| 142 ExceptionHandler(const MinidumpDescriptor& descriptor, |
| 143 FilterCallback filter, |
| 144 MinidumpCallback callback, |
| 145 void* callback_context, |
| 146 bool install_handler, |
| 147 const int server_fd, |
| 148 ContentFlags flags, |
| 149 off_t stack_size_limit); |
| 150 |
133 ~ExceptionHandler(); | 151 ~ExceptionHandler(); |
134 | 152 |
| 153 void Init(const int server_fd, bool install_handler); |
| 154 |
135 const MinidumpDescriptor& minidump_descriptor() const { | 155 const MinidumpDescriptor& minidump_descriptor() const { |
136 return minidump_descriptor_; | 156 return minidump_descriptor_; |
137 } | 157 } |
138 | 158 |
139 void set_minidump_descriptor(const MinidumpDescriptor& descriptor) { | 159 void set_minidump_descriptor(const MinidumpDescriptor& descriptor) { |
140 minidump_descriptor_ = descriptor; | 160 minidump_descriptor_ = descriptor; |
141 } | 161 } |
142 | 162 |
143 void set_crash_handler(HandlerCallback callback) { | 163 void set_crash_handler(HandlerCallback callback) { |
144 crash_handler_ = callback; | 164 crash_handler_ = callback; |
145 } | 165 } |
146 | 166 |
147 void set_crash_generation_client(CrashGenerationClient* client) { | 167 void set_crash_generation_client(CrashGenerationClient* client) { |
148 crash_generation_client_.reset(client); | 168 crash_generation_client_.reset(client); |
149 } | 169 } |
150 | 170 |
| 171 ContentFlags content_flags() const { |
| 172 return content_flags_; |
| 173 } |
| 174 |
| 175 void set_content_flags(ContentFlags flags) { |
| 176 content_flags_ = flags; |
| 177 } |
| 178 |
| 179 off_t stack_size_limit() const { |
| 180 return stack_size_limit_; |
| 181 } |
| 182 |
| 183 void set_stack_size_limit(off_t stack_size_limit) { |
| 184 stack_size_limit_ = stack_size_limit; |
| 185 } |
| 186 |
151 // Writes a minidump immediately. This can be used to capture the execution | 187 // Writes a minidump immediately. This can be used to capture the execution |
152 // state independently of a crash. | 188 // state independently of a crash. |
153 // Returns true on success. | 189 // Returns true on success. |
154 // If the ExceptionHandler has been created with a path, a new file is | 190 // If the ExceptionHandler has been created with a path, a new file is |
155 // generated for each minidump. The file path can be retrieved in the | 191 // generated for each minidump. The file path can be retrieved in the |
156 // MinidumpDescriptor passed to the MinidumpCallback or by accessing the | 192 // MinidumpDescriptor passed to the MinidumpCallback or by accessing the |
157 // MinidumpDescriptor directly from the ExceptionHandler (with | 193 // MinidumpDescriptor directly from the ExceptionHandler (with |
158 // minidump_descriptor()). | 194 // minidump_descriptor()). |
159 // If the ExceptionHandler has been created with a file descriptor, the file | 195 // If the ExceptionHandler has been created with a file descriptor, the file |
160 // descriptor is repositioned to its beginning and the previous generated | 196 // descriptor is repositioned to its beginning and the previous generated |
161 // minidump is overwritten. | 197 // minidump is overwritten. |
162 // Note that this method is not supposed to be called from a compromised | 198 // Note that this method is not supposed to be called from a compromised |
163 // context as it uses the heap. | 199 // context as it uses the heap. |
164 bool WriteMinidump(); | 200 bool WriteMinidump(); |
165 | 201 |
166 // Convenience form of WriteMinidump which does not require an | 202 // Convenience form of WriteMinidump which does not require an |
167 // ExceptionHandler instance. | 203 // ExceptionHandler instance. |
168 static bool WriteMinidump(const string& dump_path, | 204 static bool WriteMinidump(const string& dump_path, |
169 MinidumpCallback callback, | 205 MinidumpCallback callback, |
170 void* callback_context); | 206 void* callback_context, |
| 207 const ContentFlags flags, |
| 208 off_t stack_size_limit); |
| 209 |
| 210 static bool WriteMinidump(const string& dump_path, |
| 211 MinidumpCallback callback, |
| 212 void* callback_context) { |
| 213 return WriteMinidump(dump_path, |
| 214 callback, |
| 215 callback_context, |
| 216 DUMP_ALL, |
| 217 -1); |
| 218 } |
171 | 219 |
172 // Write a minidump of |child| immediately. This can be used to | 220 // Write a minidump of |child| immediately. This can be used to |
173 // capture the execution state of |child| independently of a crash. | 221 // capture the execution state of |child| independently of a crash. |
174 // Pass a meaningful |child_blamed_thread| to make that thread in | 222 // Pass a meaningful |child_blamed_thread| to make that thread in |
175 // the child process the one from which a crash signature is | 223 // the child process the one from which a crash signature is |
176 // extracted. | 224 // extracted. |
177 // | 225 // |
178 // WARNING: the return of this function *must* happen before | 226 // WARNING: the return of this function *must* happen before |
179 // the code that will eventually reap |child| executes. | 227 // the code that will eventually reap |child| executes. |
180 // Otherwise there's a pernicious race condition in which |child| | 228 // Otherwise there's a pernicious race condition in which |child| |
181 // exits, is reaped, another process created with its pid, then that | 229 // exits, is reaped, another process created with its pid, then that |
182 // new process dumped. | 230 // new process dumped. |
183 static bool WriteMinidumpForChild(pid_t child, | 231 static bool WriteMinidumpForChild(pid_t child, |
184 pid_t child_blamed_thread, | 232 pid_t child_blamed_thread, |
185 const string& dump_path, | 233 const string& dump_path, |
186 MinidumpCallback callback, | 234 MinidumpCallback callback, |
187 void* callback_context); | 235 void* callback_context, |
| 236 ContentFlags flags, |
| 237 off_t stack_size_limit); |
| 238 |
| 239 static bool WriteMinidumpForChild(pid_t child, |
| 240 pid_t child_blamed_thread, |
| 241 const string& dump_path, |
| 242 MinidumpCallback callback, |
| 243 void* callback_context) { |
| 244 return WriteMinidumpForChild(child, child_blamed_thread, |
| 245 dump_path, |
| 246 callback, |
| 247 callback_context, |
| 248 DUMP_ALL, |
| 249 -1); |
| 250 } |
188 | 251 |
189 // This structure is passed to minidump_writer.h:WriteMinidump via an opaque | 252 // This structure is passed to minidump_writer.h:WriteMinidump via an opaque |
190 // blob. It shouldn't be needed in any user code. | 253 // blob. It shouldn't be needed in any user code. |
191 struct CrashContext { | 254 struct CrashContext { |
192 siginfo_t siginfo; | 255 siginfo_t siginfo; |
193 pid_t tid; // the crashing thread. | 256 pid_t tid; // the crashing thread. |
194 struct ucontext context; | 257 struct ucontext context; |
195 #if !defined(__ARM_EABI__) && !defined(__mips__) | 258 #if !defined(__ARM_EABI__) && !defined(__mips__) |
196 // #ifdef this out because FP state is not part of user ABI for Linux ARM. | 259 // #ifdef this out because FP state is not part of user ABI for Linux ARM. |
197 // In case of MIPS Linux FP state is already part of struct | 260 // In case of MIPS Linux FP state is already part of struct |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 size_t context_size); | 307 size_t context_size); |
245 | 308 |
246 const FilterCallback filter_; | 309 const FilterCallback filter_; |
247 const MinidumpCallback callback_; | 310 const MinidumpCallback callback_; |
248 void* const callback_context_; | 311 void* const callback_context_; |
249 | 312 |
250 scoped_ptr<CrashGenerationClient> crash_generation_client_; | 313 scoped_ptr<CrashGenerationClient> crash_generation_client_; |
251 | 314 |
252 MinidumpDescriptor minidump_descriptor_; | 315 MinidumpDescriptor minidump_descriptor_; |
253 | 316 |
| 317 ContentFlags content_flags_; |
| 318 off_t stack_size_limit_; |
| 319 |
254 // Must be volatile. The compiler is unaware of the code which runs in | 320 // Must be volatile. The compiler is unaware of the code which runs in |
255 // the signal handler which reads this variable. Without volatile the | 321 // the signal handler which reads this variable. Without volatile the |
256 // compiler is free to optimise away writes to this variable which it | 322 // compiler is free to optimise away writes to this variable which it |
257 // believes are never read. | 323 // believes are never read. |
258 volatile HandlerCallback crash_handler_; | 324 volatile HandlerCallback crash_handler_; |
259 | 325 |
260 // We need to explicitly enable ptrace of parent processes on some | 326 // We need to explicitly enable ptrace of parent processes on some |
261 // kernels, but we need to know the PID of the cloned process before we | 327 // kernels, but we need to know the PID of the cloned process before we |
262 // can do this. We create a pipe which we can use to block the | 328 // can do this. We create a pipe which we can use to block the |
263 // cloned process after creating it, until we have explicitly enabled | 329 // cloned process after creating it, until we have explicitly enabled |
264 // ptrace. This is used to store the file descriptors for the pipe | 330 // ptrace. This is used to store the file descriptors for the pipe |
265 int fdes[2]; | 331 int fdes[2]; |
266 | 332 |
267 // Callers can add extra info about mappings for cases where the | 333 // Callers can add extra info about mappings for cases where the |
268 // dumper code cannot extract enough information from /proc/<pid>/maps. | 334 // dumper code cannot extract enough information from /proc/<pid>/maps. |
269 MappingList mapping_list_; | 335 MappingList mapping_list_; |
270 | 336 |
271 // Callers can request additional memory regions to be included in | 337 // Callers can request additional memory regions to be included in |
272 // the dump. | 338 // the dump. |
273 AppMemoryList app_memory_list_; | 339 AppMemoryList app_memory_list_; |
274 }; | 340 }; |
275 | 341 |
276 } // namespace google_breakpad | 342 } // namespace google_breakpad |
277 | 343 |
278 #endif // CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H_ | 344 #endif // CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H_ |
OLD | NEW |