OLD | NEW |
1 // Copyright (c) 2009, Google Inc. | 1 // Copyright (c) 2009, 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 #include <unistd.h> | 80 #include <unistd.h> |
81 | 81 |
82 #include "common/linux/linux_libc_support.h" | 82 #include "common/linux/linux_libc_support.h" |
83 #include "common/linux/linux_syscall_support.h" | 83 #include "common/linux/linux_syscall_support.h" |
84 #include "common/linux/memory.h" | 84 #include "common/linux/memory.h" |
85 #include "client/linux/minidump_writer//minidump_writer.h" | 85 #include "client/linux/minidump_writer//minidump_writer.h" |
86 #include "common/linux/guid_creator.h" | 86 #include "common/linux/guid_creator.h" |
87 | 87 |
88 // A wrapper for the tgkill syscall: send a signal to a specific thread. | 88 // A wrapper for the tgkill syscall: send a signal to a specific thread. |
89 static int tgkill(pid_t tgid, pid_t tid, int sig) { | 89 static int tgkill(pid_t tgid, pid_t tid, int sig) { |
90 syscall(__NR_tgkill, tgid, tid, sig); | 90 return syscall(__NR_tgkill, tgid, tid, sig); |
91 } | 91 } |
92 | 92 |
93 namespace google_breakpad { | 93 namespace google_breakpad { |
94 | 94 |
95 // The list of signals which we consider to be crashes. The default action for | 95 // The list of signals which we consider to be crashes. The default action for |
96 // all these signals must be Core (see man 7 signal) because we rethrow the | 96 // all these signals must be Core (see man 7 signal) because we rethrow the |
97 // signal after handling it and expect that it'll be fatal. | 97 // signal after handling it and expect that it'll be fatal. |
98 static const int kExceptionSignals[] = { | 98 static const int kExceptionSignals[] = { |
99 SIGSEGV, SIGABRT, SIGFPE, SIGILL, SIGBUS, -1 | 99 SIGSEGV, SIGABRT, SIGFPE, SIGILL, SIGBUS, -1 |
100 }; | 100 }; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 | 164 |
165 sa.sa_sigaction = SignalHandler; | 165 sa.sa_sigaction = SignalHandler; |
166 sa.sa_flags = SA_ONSTACK | SA_SIGINFO; | 166 sa.sa_flags = SA_ONSTACK | SA_SIGINFO; |
167 | 167 |
168 for (unsigned i = 0; kExceptionSignals[i] != -1; ++i) { | 168 for (unsigned i = 0; kExceptionSignals[i] != -1; ++i) { |
169 struct sigaction* old = new struct sigaction; | 169 struct sigaction* old = new struct sigaction; |
170 if (sigaction(kExceptionSignals[i], &sa, old) == -1) | 170 if (sigaction(kExceptionSignals[i], &sa, old) == -1) |
171 return false; | 171 return false; |
172 old_handlers_.push_back(std::make_pair(kExceptionSignals[i], old)); | 172 old_handlers_.push_back(std::make_pair(kExceptionSignals[i], old)); |
173 } | 173 } |
| 174 return true; |
174 } | 175 } |
175 | 176 |
176 // Runs before crashing: normal context. | 177 // Runs before crashing: normal context. |
177 void ExceptionHandler::UninstallHandlers() { | 178 void ExceptionHandler::UninstallHandlers() { |
178 for (unsigned i = 0; i < old_handlers_.size(); ++i) { | 179 for (unsigned i = 0; i < old_handlers_.size(); ++i) { |
179 struct sigaction *action = | 180 struct sigaction *action = |
180 reinterpret_cast<struct sigaction*>(old_handlers_[i].second); | 181 reinterpret_cast<struct sigaction*>(old_handlers_[i].second); |
181 sigaction(old_handlers_[i].first, action, NULL); | 182 sigaction(old_handlers_[i].first, action, NULL); |
182 delete action; | 183 delete action; |
183 } | 184 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 bool ExceptionHandler::HandleSignal(int sig, siginfo_t* info, void* uc) { | 258 bool ExceptionHandler::HandleSignal(int sig, siginfo_t* info, void* uc) { |
258 if (filter_ && !filter_(callback_context_)) | 259 if (filter_ && !filter_(callback_context_)) |
259 return false; | 260 return false; |
260 | 261 |
261 // Allow ourselves to be dumped. | 262 // Allow ourselves to be dumped. |
262 sys_prctl(PR_SET_DUMPABLE, 1); | 263 sys_prctl(PR_SET_DUMPABLE, 1); |
263 | 264 |
264 CrashContext context; | 265 CrashContext context; |
265 memcpy(&context.siginfo, info, sizeof(siginfo_t)); | 266 memcpy(&context.siginfo, info, sizeof(siginfo_t)); |
266 memcpy(&context.context, uc, sizeof(struct ucontext)); | 267 memcpy(&context.context, uc, sizeof(struct ucontext)); |
| 268 #if !defined(__ARM_ARCH_7A__) |
| 269 // FP state is not part of user ABI on ARM Linux. |
267 memcpy(&context.float_state, ((struct ucontext *)uc)->uc_mcontext.fpregs, | 270 memcpy(&context.float_state, ((struct ucontext *)uc)->uc_mcontext.fpregs, |
268 sizeof(context.float_state)); | 271 sizeof(context.float_state)); |
| 272 #endif |
269 context.tid = sys_gettid(); | 273 context.tid = sys_gettid(); |
270 | 274 |
271 if (crash_handler_ && crash_handler_(&context, sizeof(context), | 275 if (crash_handler_ && crash_handler_(&context, sizeof(context), |
272 callback_context_)) | 276 callback_context_)) |
273 return true; | 277 return true; |
274 | 278 |
275 static const unsigned kChildStackSize = 8000; | 279 static const unsigned kChildStackSize = 8000; |
276 PageAllocator allocator; | 280 PageAllocator allocator; |
277 uint8_t* stack = (uint8_t*) allocator.Alloc(kChildStackSize); | 281 uint8_t* stack = (uint8_t*) allocator.Alloc(kChildStackSize); |
278 if (!stack) | 282 if (!stack) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 | 317 |
314 // This function runs in a compromised context: see the top of the file. | 318 // This function runs in a compromised context: see the top of the file. |
315 // Runs on the cloned process. | 319 // Runs on the cloned process. |
316 bool ExceptionHandler::DoDump(pid_t crashing_process, const void* context, | 320 bool ExceptionHandler::DoDump(pid_t crashing_process, const void* context, |
317 size_t context_size) { | 321 size_t context_size) { |
318 return google_breakpad::WriteMinidump( | 322 return google_breakpad::WriteMinidump( |
319 next_minidump_path_c_, crashing_process, context, context_size); | 323 next_minidump_path_c_, crashing_process, context, context_size); |
320 } | 324 } |
321 | 325 |
322 } // namespace google_breakpad | 326 } // namespace google_breakpad |
OLD | NEW |