aboutsummaryrefslogtreecommitdiff
path: root/src/client/linux/handler/exception_handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/linux/handler/exception_handler.cc')
-rw-r--r--src/client/linux/handler/exception_handler.cc44
1 files changed, 32 insertions, 12 deletions
diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc
index 01081878..038612f2 100644
--- a/src/client/linux/handler/exception_handler.cc
+++ b/src/client/linux/handler/exception_handler.cc
@@ -80,6 +80,9 @@
#include <ucontext.h>
#include <unistd.h>
+#include <algorithm>
+#include <vector>
+
#include "common/linux/linux_libc_support.h"
#include "common/linux/linux_syscall_support.h"
#include "common/linux/memory.h"
@@ -88,7 +91,7 @@
// A wrapper for the tgkill syscall: send a signal to a specific thread.
static int tgkill(pid_t tgid, pid_t tid, int sig) {
- syscall(__NR_tgkill, tgid, tid, sig);
+ return syscall(__NR_tgkill, tgid, tid, sig);
return 0;
}
@@ -145,7 +148,6 @@ void ExceptionHandler::Init(const std::string &dump_path,
const int server_fd)
{
crash_handler_ = NULL;
-
if (0 <= server_fd)
crash_generation_client_
.reset(CrashGenerationClient::TryCreate(server_fd));
@@ -209,7 +211,11 @@ void ExceptionHandler::UninstallHandlers() {
sigaction(old_handlers_[i].first, action, NULL);
delete action;
}
-
+ pthread_mutex_lock(&handler_stack_mutex_);
+ std::vector<ExceptionHandler*>::iterator handler =
+ std::find(handler_stack_->begin(), handler_stack_->end(), this);
+ handler_stack_->erase(handler);
+ pthread_mutex_unlock(&handler_stack_mutex_);
old_handlers_.clear();
}
@@ -231,12 +237,15 @@ void ExceptionHandler::UpdateNextID() {
}
}
+// void ExceptionHandler::set_crash_handler(HandlerCallback callback) {
+// crash_handler_ = callback;
+// }
+
// This function runs in a compromised context: see the top of the file.
// Runs on the crashing thread.
// static
void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) {
// All the exception signals are blocked at this point.
-
pthread_mutex_lock(&handler_stack_mutex_);
if (!handler_stack_->size()) {
@@ -288,18 +297,25 @@ bool ExceptionHandler::HandleSignal(int sig, siginfo_t* info, void* uc) {
// Allow ourselves to be dumped.
sys_prctl(PR_SET_DUMPABLE, 1);
-
CrashContext context;
memcpy(&context.siginfo, info, sizeof(siginfo_t));
memcpy(&context.context, uc, sizeof(struct ucontext));
- memcpy(&context.float_state, ((struct ucontext *)uc)->uc_mcontext.fpregs,
- sizeof(context.float_state));
+#if !defined(__ARM_EABI__)
+ // FP state is not part of user ABI on ARM Linux.
+ struct ucontext *uc_ptr = (struct ucontext*)uc;
+ if (uc_ptr->uc_mcontext.fpregs) {
+ memcpy(&context.float_state,
+ uc_ptr->uc_mcontext.fpregs,
+ sizeof(context.float_state));
+ }
+#endif
context.tid = sys_gettid();
-
- if (crash_handler_ && crash_handler_(&context, sizeof(context),
- callback_context_))
- return true;
-
+ if (crash_handler_ != NULL) {
+ if (crash_handler_(&context, sizeof(context),
+ callback_context_)) {
+ return true;
+ }
+ }
return GenerateDump(&context);
}
@@ -364,6 +380,7 @@ bool ExceptionHandler::WriteMinidump(const std::string &dump_path,
}
bool ExceptionHandler::WriteMinidump() {
+#if !defined(__ARM_EABI__)
// Allow ourselves to be dumped.
sys_prctl(PR_SET_DUMPABLE, 1);
@@ -378,6 +395,9 @@ bool ExceptionHandler::WriteMinidump() {
bool success = GenerateDump(&context);
UpdateNextID();
return success;
+#else
+ return false;
+#endif // !defined(__ARM_EABI__)
}
} // namespace google_breakpad