From aaeb7e4f13f65832e20c417c5573c57ac1367b7c Mon Sep 17 00:00:00 2001 From: "ted.mielczarek@gmail.com" Date: Wed, 14 Aug 2013 17:14:18 +0000 Subject: [PATCH] Enable the SIGABRT handler on desktop OS X R=mark at https://breakpad.appspot.com/618002/ git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1205 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/client/mac/handler/exception_handler.cc | 2 - src/client/mac/handler/minidump_generator.cc | 13 ++++++ .../mac/tests/exception_handler_test.cc | 46 ++++++++++++++++--- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/client/mac/handler/exception_handler.cc b/src/client/mac/handler/exception_handler.cc index ebaf857e..e2ae4e31 100644 --- a/src/client/mac/handler/exception_handler.cc +++ b/src/client/mac/handler/exception_handler.cc @@ -626,7 +626,6 @@ bool ExceptionHandler::InstallHandler() { if (gProtectedData.handler != NULL) { return false; } -#if TARGET_OS_IPHONE if (!IsOutOfProcess()) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); @@ -646,7 +645,6 @@ bool ExceptionHandler::InstallHandler() { mprotect(gProtectedData.protected_buffer, PAGE_SIZE, PROT_READ); #endif } -#endif try { #if USE_PROTECTED_ALLOCATIONS diff --git a/src/client/mac/handler/minidump_generator.cc b/src/client/mac/handler/minidump_generator.cc index 85c53ebb..809e684f 100644 --- a/src/client/mac/handler/minidump_generator.cc +++ b/src/client/mac/handler/minidump_generator.cc @@ -787,9 +787,22 @@ bool MinidumpGenerator::GetThreadState(thread_act_t target_thread, *count = final_size; return true; } +#endif +#ifdef HAS_X86_SUPPORT + case CPU_TYPE_I386: + case CPU_TYPE_X86_64: { + size_t state_size = cpu_type_ == CPU_TYPE_I386 ? + sizeof(i386_thread_state_t) : sizeof(x86_thread_state64_t); + size_t final_size = + std::min(static_cast(*count), state_size); + memcpy(state, &task_context_->uc_mcontext->__ss, final_size); + *count = final_size; + return true; + } #endif } } + thread_state_flavor_t flavor; switch (cpu_type_) { #ifdef HAS_ARM_SUPPORT diff --git a/src/client/mac/tests/exception_handler_test.cc b/src/client/mac/tests/exception_handler_test.cc index d108d432..e19944d0 100644 --- a/src/client/mac/tests/exception_handler_test.cc +++ b/src/client/mac/tests/exception_handler_test.cc @@ -122,10 +122,46 @@ void ExceptionHandlerTest::InProcessCrash(bool aborting) { char minidump_file[PATH_MAX]; ssize_t nbytes = read(fds[0], minidump_file, sizeof(minidump_file)); ASSERT_NE(0, nbytes); - // Ensure that minidump file exists and is > 0 bytes. - struct stat st; - ASSERT_EQ(0, stat(minidump_file, &st)); - ASSERT_LT(0, st.st_size); + + Minidump minidump(minidump_file); + ASSERT_TRUE(minidump.Read()); + + MinidumpException* exception = minidump.GetException(); + ASSERT_TRUE(exception); + + const MDRawExceptionStream* raw_exception = exception->exception(); + ASSERT_TRUE(raw_exception); + + if (aborting) { + EXPECT_EQ(MD_EXCEPTION_MAC_SOFTWARE, + raw_exception->exception_record.exception_code); + EXPECT_EQ(MD_EXCEPTION_CODE_MAC_ABORT, + raw_exception->exception_record.exception_flags); + } else { + EXPECT_EQ(MD_EXCEPTION_MAC_BAD_ACCESS, + raw_exception->exception_record.exception_code); +#if defined(__x86_64__) + EXPECT_EQ(MD_EXCEPTION_CODE_MAC_INVALID_ADDRESS, + raw_exception->exception_record.exception_flags); +#elif defined(__i386__) + EXPECT_EQ(MD_EXCEPTION_CODE_MAC_PROTECTION_FAILURE, + raw_exception->exception_record.exception_flags); +#endif + } + + const MinidumpContext* context = exception->GetContext(); + ASSERT_TRUE(context); + + uint64_t instruction_pointer; + ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer)); + + // Ideally would like to sanity check that abort() is on the stack + // but that's hard. + MinidumpMemoryList* memory_list = minidump.GetMemoryList(); + ASSERT_TRUE(memory_list); + MinidumpMemoryRegion* region = + memory_list->GetMemoryRegionForAddress(instruction_pointer); + EXPECT_TRUE(region); // Child process should have exited with a zero status. int ret; @@ -138,11 +174,9 @@ TEST_F(ExceptionHandlerTest, InProcess) { InProcessCrash(false); } -#if TARGET_OS_IPHONE TEST_F(ExceptionHandlerTest, InProcessAbort) { InProcessCrash(true); } -#endif static bool DumpNameMDCallback(const char *dump_dir, const char *file_name, void *context, bool success) {