mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2025-07-08 19:40:36 +00:00
Undo suspend/resume feature since it was meant as a workaround to a bug in how we handled child process exceptions. Currently we don't return to the kernel when we take an exception from a child process, causing a hang. Now we return KERN_FAILURE, indicating to the kernel to move on to the host-level exception handler(usually Crash Reporter)
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@292 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
32441cc060
commit
3a283d8f8b
|
@ -206,6 +206,10 @@ kern_return_t breakpad_exception_raise(mach_port_t port, mach_port_t failed_thre
|
||||||
exception_type_t exception,
|
exception_type_t exception,
|
||||||
exception_data_t code,
|
exception_data_t code,
|
||||||
mach_msg_type_number_t code_count) {
|
mach_msg_type_number_t code_count) {
|
||||||
|
|
||||||
|
if (task != mach_task_self()) {
|
||||||
|
return KERN_FAILURE;
|
||||||
|
}
|
||||||
return ForwardException(task, failed_thread, exception, code, code_count);
|
return ForwardException(task, failed_thread, exception, code, code_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +455,7 @@ void *ExceptionHandler::WaitForMessage(void *exception_handler_class) {
|
||||||
// Uninstall our handler so that we don't get in a loop if the process of
|
// Uninstall our handler so that we don't get in a loop if the process of
|
||||||
// writing out a minidump causes an exception. However, if the exception
|
// writing out a minidump causes an exception. However, if the exception
|
||||||
// was caused by a fork'd process, don't uninstall things
|
// was caused by a fork'd process, don't uninstall things
|
||||||
if (receive.task.name == mach_task_self())
|
|
||||||
// If the actual exception code is zero, then we're calling this handler
|
// If the actual exception code is zero, then we're calling this handler
|
||||||
// in a way that indicates that we want to either exit this thread or
|
// in a way that indicates that we want to either exit this thread or
|
||||||
// generate a minidump
|
// generate a minidump
|
||||||
|
@ -491,7 +495,10 @@ void *ExceptionHandler::WaitForMessage(void *exception_handler_class) {
|
||||||
// if the child crashes, it will send the exception back to the parent
|
// if the child crashes, it will send the exception back to the parent
|
||||||
// process. The check for task == self_task() ensures that only
|
// process. The check for task == self_task() ensures that only
|
||||||
// exceptions that occur in the parent process are caught and
|
// exceptions that occur in the parent process are caught and
|
||||||
// processed.
|
// processed. If the exception was not caused by this task, we
|
||||||
|
// still need to call into the exception server and have it return
|
||||||
|
// KERN_FAILURE (see breakpad_exception_raise) in order for the kernel
|
||||||
|
// to move onto the host exception handler for the child task
|
||||||
if (receive.task.name == mach_task_self()) {
|
if (receive.task.name == mach_task_self()) {
|
||||||
self->SuspendThreads();
|
self->SuspendThreads();
|
||||||
|
|
||||||
|
@ -510,21 +517,18 @@ void *ExceptionHandler::WaitForMessage(void *exception_handler_class) {
|
||||||
if(gBreakpadAllocator)
|
if(gBreakpadAllocator)
|
||||||
gBreakpadAllocator->Protect();
|
gBreakpadAllocator->Protect();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Pass along the exception to the server, which will setup the
|
|
||||||
// message and call catch_exception_raise() and put the KERN_SUCCESS
|
|
||||||
// into the reply.
|
|
||||||
ExceptionReplyMessage reply;
|
|
||||||
if (!exc_server(&receive.header, &reply.header))
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
// Send a reply and exit
|
|
||||||
result = mach_msg(&(reply.header), MACH_SEND_MSG,
|
|
||||||
reply.header.msgh_size, 0, MACH_PORT_NULL,
|
|
||||||
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
|
|
||||||
} else {
|
|
||||||
// An exception occurred in a child process
|
|
||||||
}
|
}
|
||||||
|
// Pass along the exception to the server, which will setup the
|
||||||
|
// message and call breakpad_exception_raise() and put the return
|
||||||
|
// code into the reply.
|
||||||
|
ExceptionReplyMessage reply;
|
||||||
|
if (!exc_server(&receive.header, &reply.header))
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
// Send a reply and exit
|
||||||
|
result = mach_msg(&(reply.header), MACH_SEND_MSG,
|
||||||
|
reply.header.msgh_size, 0, MACH_PORT_NULL,
|
||||||
|
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -600,36 +604,6 @@ bool ExceptionHandler::UninstallHandler(bool in_exception) {
|
||||||
return result == KERN_SUCCESS;
|
return result == KERN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExceptionHandler::SuspendExceptionHandling() {
|
|
||||||
if (!installed_exception_handler_) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return UninstallHandler(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool ExceptionHandler::ResumeExceptionHandling() {
|
|
||||||
|
|
||||||
if (installed_exception_handler_) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This conditional means that Setup() has never been
|
|
||||||
// called, but since it's called from the constructor
|
|
||||||
// we should never hit this.
|
|
||||||
assert(handler_port_);
|
|
||||||
if (handler_port_ == MACH_PORT_NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return InstallHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ExceptionHandler::ExceptionHandlerIsSuspended() {
|
|
||||||
return handler_port_ != MACH_PORT_NULL && !installed_exception_handler_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ExceptionHandler::Setup(bool install_handler) {
|
bool ExceptionHandler::Setup(bool install_handler) {
|
||||||
if (pthread_mutex_init(&minidump_write_mutex_, NULL))
|
if (pthread_mutex_init(&minidump_write_mutex_, NULL))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -114,21 +114,6 @@ class ExceptionHandler {
|
||||||
static bool WriteMinidump(const string &dump_path, MinidumpCallback callback,
|
static bool WriteMinidump(const string &dump_path, MinidumpCallback callback,
|
||||||
void *callback_context);
|
void *callback_context);
|
||||||
|
|
||||||
// Temporarily stop this class from receiving exceptions
|
|
||||||
// Returns true if exception handling was successfully suspended
|
|
||||||
// It's an error to call this function if exception handling is
|
|
||||||
// not installed(we return false)
|
|
||||||
bool SuspendExceptionHandling();
|
|
||||||
|
|
||||||
// Resume this class from receiving exceptions
|
|
||||||
// Returns true if exception handling was successfully resumed
|
|
||||||
// It's an error to call this function if exception handling is
|
|
||||||
// already installed
|
|
||||||
bool ResumeExceptionHandling();
|
|
||||||
|
|
||||||
// Tell caller whether we're setup to handle exceptions or not
|
|
||||||
bool ExceptionHandlerIsSuspended();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Install the mach exception handler
|
// Install the mach exception handler
|
||||||
bool InstallHandler();
|
bool InstallHandler();
|
||||||
|
|
Loading…
Reference in a new issue