bug 717758 - handle abort() in Breakpad on OS X. r=mento

This commit is contained in:
Ted Mielczarek 2013-09-16 14:44:24 -04:00
Родитель 523d787b77
Коммит 2153060e50
3 изменённых файлов: 53 добавлений и 8 удалений

Просмотреть файл

@ -626,7 +626,6 @@ bool ExceptionHandler::InstallHandler() {
if (gProtectedData.handler != NULL) { if (gProtectedData.handler != NULL) {
return false; return false;
} }
#if TARGET_OS_IPHONE
if (!IsOutOfProcess()) { if (!IsOutOfProcess()) {
struct sigaction sa; struct sigaction sa;
memset(&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
@ -646,7 +645,6 @@ bool ExceptionHandler::InstallHandler() {
mprotect(gProtectedData.protected_buffer, PAGE_SIZE, PROT_READ); mprotect(gProtectedData.protected_buffer, PAGE_SIZE, PROT_READ);
#endif #endif
} }
#endif
try { try {
#if USE_PROTECTED_ALLOCATIONS #if USE_PROTECTED_ALLOCATIONS

Просмотреть файл

@ -787,9 +787,22 @@ bool MinidumpGenerator::GetThreadState(thread_act_t target_thread,
*count = final_size; *count = final_size;
return true; 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<size_t>(*count), state_size);
memcpy(state, &task_context_->uc_mcontext->__ss, final_size);
*count = final_size;
return true;
}
#endif #endif
} }
} }
thread_state_flavor_t flavor; thread_state_flavor_t flavor;
switch (cpu_type_) { switch (cpu_type_) {
#ifdef HAS_ARM_SUPPORT #ifdef HAS_ARM_SUPPORT

Просмотреть файл

@ -122,10 +122,46 @@ void ExceptionHandlerTest::InProcessCrash(bool aborting) {
char minidump_file[PATH_MAX]; char minidump_file[PATH_MAX];
ssize_t nbytes = read(fds[0], minidump_file, sizeof(minidump_file)); ssize_t nbytes = read(fds[0], minidump_file, sizeof(minidump_file));
ASSERT_NE(0, nbytes); ASSERT_NE(0, nbytes);
// Ensure that minidump file exists and is > 0 bytes.
struct stat st; Minidump minidump(minidump_file);
ASSERT_EQ(0, stat(minidump_file, &st)); ASSERT_TRUE(minidump.Read());
ASSERT_LT(0, st.st_size);
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. // Child process should have exited with a zero status.
int ret; int ret;
@ -138,11 +174,9 @@ TEST_F(ExceptionHandlerTest, InProcess) {
InProcessCrash(false); InProcessCrash(false);
} }
#if TARGET_OS_IPHONE
TEST_F(ExceptionHandlerTest, InProcessAbort) { TEST_F(ExceptionHandlerTest, InProcessAbort) {
InProcessCrash(true); InProcessCrash(true);
} }
#endif
static bool DumpNameMDCallback(const char *dump_dir, const char *file_name, static bool DumpNameMDCallback(const char *dump_dir, const char *file_name,
void *context, bool success) { void *context, bool success) {