зеркало из https://github.com/mozilla/gecko-dev.git
bug 717758 - handle abort() in Breakpad on OS X. r=mento
This commit is contained in:
Родитель
523d787b77
Коммит
2153060e50
|
@ -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) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче