| 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 |