From de545c09d0363e6964822ec92529a80feaca152d Mon Sep 17 00:00:00 2001 From: nealsid Date: Tue, 2 Mar 2010 00:39:48 +0000 Subject: ARM support, with some build system changes to support x86-64, arm, and i386 in an autoconf style build in Linux. The O2 build for the unit tests is still broken but I'm checking this in to unblock people A=nealsid R=ajwong, hannahtang, ted.mielczarek git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@541 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/client/linux/handler/exception_handler.cc | 44 ++++++++++++++++------ src/client/linux/handler/exception_handler.h | 6 +++ .../linux/handler/exception_handler_unittest.cc | 11 ++---- 3 files changed, 42 insertions(+), 19 deletions(-) (limited to 'src/client/linux/handler') 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 #include +#include +#include + #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::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 diff --git a/src/client/linux/handler/exception_handler.h b/src/client/linux/handler/exception_handler.h index 6182a6c1..2a497037 100644 --- a/src/client/linux/handler/exception_handler.h +++ b/src/client/linux/handler/exception_handler.h @@ -34,6 +34,7 @@ #include #include +#include #include "client/linux/crash_generation/crash_generation_client.h" #include "processor/scoped_ptr.h" @@ -42,6 +43,8 @@ struct sigaction; namespace google_breakpad { +class ExceptionHandler; + // ExceptionHandler // // ExceptionHandler can write a minidump file when an exception occurs, @@ -163,7 +166,10 @@ class ExceptionHandler { siginfo_t siginfo; pid_t tid; // the crashing thread. struct ucontext context; +#if !defined(__ARM_EABI__) + // #ifdef this out because FP state is not part of user ABI for Linux ARM. struct _libc_fpstate float_state; +#endif }; // Returns whether out-of-process dump generation is used or not. diff --git a/src/client/linux/handler/exception_handler_unittest.cc b/src/client/linux/handler/exception_handler_unittest.cc index 2e8a6dbe..9747fe71 100644 --- a/src/client/linux/handler/exception_handler_unittest.cc +++ b/src/client/linux/handler/exception_handler_unittest.cc @@ -36,7 +36,7 @@ #include #include -#include "client/linux/handler//exception_handler.h" +#include "client/linux/handler/exception_handler.h" #include "client/linux/minidump_writer/minidump_writer.h" #include "common/linux/eintr_wrapper.h" #include "common/linux/linux_libc_support.h" @@ -112,8 +112,8 @@ TEST(ExceptionHandlerTest, ChildCrash) { ASSERT_TRUE(pfd.revents & POLLIN); uint32_t len; - ASSERT_EQ(read(fds[0], &len, sizeof(len)), sizeof(len)); - ASSERT_LT(len, 2048); + ASSERT_EQ(read(fds[0], &len, sizeof(len)), (ssize_t)sizeof(len)); + ASSERT_LT(len, (uint32_t)2048); char* filename = reinterpret_cast(malloc(len + 1)); ASSERT_EQ(read(fds[0], filename, len), len); filename[len] = 0; @@ -137,12 +137,10 @@ CrashHandler(const void* crash_context, size_t crash_context_size, const int fd = (intptr_t) context; int fds[2]; pipe(fds); - struct kernel_msghdr msg = {0}; struct kernel_iovec iov; iov.iov_base = const_cast(crash_context); iov.iov_len = crash_context_size; - msg.msg_iov = &iov; msg.msg_iovlen = 1; char cmsg[kControlMsgSize]; @@ -183,11 +181,10 @@ TEST(ExceptionHandlerTest, ExternalDumper) { const pid_t child = fork(); if (child == 0) { close(fds[0]); - ExceptionHandler handler("/tmp", NULL, NULL, (void*) fds[1], true); + ExceptionHandler handler("/tmp1", NULL, NULL, (void*) fds[1], true); handler.set_crash_handler(CrashHandler); *reinterpret_cast(NULL) = 0; } - close(fds[1]); struct msghdr msg = {0}; struct iovec iov; -- cgit v1.2.1