mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2025-07-18 13:37:39 +00:00
Change iOS implementation to not use exc_server
Instead of using exc_server, the message is parsed directly, and the minidump is created, then the app is killed. Moreover, the only catch exception is exception_raise. This patch remove all rereference to exception_raise_state and exception_raise_state_identity. Review URL: https://breakpad.appspot.com/358001 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@934 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
b1f858f26b
commit
7facb6a6fb
|
@ -28,6 +28,8 @@
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <mach/exc.h>
|
||||||
|
#include <mach/mig.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <TargetConditionals.h>
|
#include <TargetConditionals.h>
|
||||||
|
@ -99,6 +101,7 @@ struct ExceptionReplyMessage {
|
||||||
exception_mask_t s_exception_mask = EXC_MASK_BAD_ACCESS |
|
exception_mask_t s_exception_mask = EXC_MASK_BAD_ACCESS |
|
||||||
EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC | EXC_MASK_BREAKPOINT;
|
EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC | EXC_MASK_BREAKPOINT;
|
||||||
|
|
||||||
|
#if !TARGET_OS_IPHONE
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
// Forward declarations for functions that need "C" style compilation
|
// Forward declarations for functions that need "C" style compilation
|
||||||
|
@ -114,6 +117,8 @@ extern "C"
|
||||||
exception_data_t code,
|
exception_data_t code,
|
||||||
mach_msg_type_number_t code_count)
|
mach_msg_type_number_t code_count)
|
||||||
__attribute__((visibility("default")));
|
__attribute__((visibility("default")));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
kern_return_t ForwardException(mach_port_t task,
|
kern_return_t ForwardException(mach_port_t task,
|
||||||
mach_port_t failed_thread,
|
mach_port_t failed_thread,
|
||||||
|
@ -121,40 +126,83 @@ extern "C"
|
||||||
exception_data_t code,
|
exception_data_t code,
|
||||||
mach_msg_type_number_t code_count);
|
mach_msg_type_number_t code_count);
|
||||||
|
|
||||||
kern_return_t exception_raise(mach_port_t target_port,
|
#if TARGET_OS_IPHONE
|
||||||
mach_port_t failed_thread,
|
// Implementation is based on the implementation generated by mig.
|
||||||
mach_port_t task,
|
boolean_t breakpad_exc_server(mach_msg_header_t *InHeadP,
|
||||||
exception_type_t exception,
|
mach_msg_header_t *OutHeadP) {
|
||||||
exception_data_t exception_code,
|
OutHeadP->msgh_bits =
|
||||||
mach_msg_type_number_t exception_code_count);
|
MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(InHeadP->msgh_bits), 0);
|
||||||
|
OutHeadP->msgh_remote_port = InHeadP->msgh_remote_port;
|
||||||
|
/* Minimal size: routine() will update it if different */
|
||||||
|
OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t);
|
||||||
|
OutHeadP->msgh_local_port = MACH_PORT_NULL;
|
||||||
|
OutHeadP->msgh_id = InHeadP->msgh_id + 100;
|
||||||
|
|
||||||
kern_return_t
|
if (InHeadP->msgh_id != 2401) {
|
||||||
exception_raise_state(mach_port_t target_port,
|
((mig_reply_error_t *)OutHeadP)->NDR = NDR_record;
|
||||||
mach_port_t failed_thread,
|
((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID;
|
||||||
mach_port_t task,
|
return FALSE;
|
||||||
exception_type_t exception,
|
|
||||||
exception_data_t exception_code,
|
|
||||||
mach_msg_type_number_t code_count,
|
|
||||||
thread_state_flavor_t *target_flavor,
|
|
||||||
thread_state_t in_thread_state,
|
|
||||||
mach_msg_type_number_t in_thread_state_count,
|
|
||||||
thread_state_t out_thread_state,
|
|
||||||
mach_msg_type_number_t *out_thread_state_count);
|
|
||||||
|
|
||||||
kern_return_t
|
|
||||||
exception_raise_state_identity(mach_port_t target_port,
|
|
||||||
mach_port_t failed_thread,
|
|
||||||
mach_port_t task,
|
|
||||||
exception_type_t exception,
|
|
||||||
exception_data_t exception_code,
|
|
||||||
mach_msg_type_number_t exception_code_count,
|
|
||||||
thread_state_flavor_t *target_flavor,
|
|
||||||
thread_state_t in_thread_state,
|
|
||||||
mach_msg_type_number_t in_thread_state_count,
|
|
||||||
thread_state_t out_thread_state,
|
|
||||||
mach_msg_type_number_t *out_thread_state_count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __MigPackStructs
|
||||||
|
#pragma pack(4)
|
||||||
|
#endif
|
||||||
|
typedef struct {
|
||||||
|
mach_msg_header_t Head;
|
||||||
|
/* start of the kernel processed data */
|
||||||
|
mach_msg_body_t msgh_body;
|
||||||
|
mach_msg_port_descriptor_t thread;
|
||||||
|
mach_msg_port_descriptor_t task;
|
||||||
|
/* end of the kernel processed data */
|
||||||
|
NDR_record_t NDR;
|
||||||
|
exception_type_t exception;
|
||||||
|
mach_msg_type_number_t codeCnt;
|
||||||
|
integer_t code[2];
|
||||||
|
mach_msg_trailer_t trailer;
|
||||||
|
} Request;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
mach_msg_header_t Head;
|
||||||
|
NDR_record_t NDR;
|
||||||
|
kern_return_t RetCode;
|
||||||
|
} Reply;
|
||||||
|
#ifdef __MigPackStructs
|
||||||
|
#pragma pack()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Request *In0P = (Request *)InHeadP;
|
||||||
|
Reply *OutP = (Reply *)OutHeadP;
|
||||||
|
|
||||||
|
if (In0P->task.name != mach_task_self()) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
OutP->RetCode = ForwardException(In0P->task.name,
|
||||||
|
In0P->thread.name,
|
||||||
|
In0P->exception,
|
||||||
|
In0P->code,
|
||||||
|
In0P->codeCnt);
|
||||||
|
OutP->NDR = NDR_record;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
boolean_t breakpad_exc_server(mach_msg_header_t *request,
|
||||||
|
mach_msg_header_t *reply) {
|
||||||
|
return exc_server(request, reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback from exc_server()
|
||||||
|
kern_return_t catch_exception_raise(mach_port_t port, mach_port_t failed_thread,
|
||||||
|
mach_port_t task,
|
||||||
|
exception_type_t exception,
|
||||||
|
exception_data_t code,
|
||||||
|
mach_msg_type_number_t code_count) {
|
||||||
|
if (task != mach_task_self()) {
|
||||||
|
return KERN_FAILURE;
|
||||||
|
}
|
||||||
|
return ForwardException(task, failed_thread, exception, code, code_count);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ExceptionHandler::ExceptionHandler(const string &dump_path,
|
ExceptionHandler::ExceptionHandler(const string &dump_path,
|
||||||
FilterCallback filter,
|
FilterCallback filter,
|
||||||
MinidumpCallback callback,
|
MinidumpCallback callback,
|
||||||
|
@ -380,10 +428,7 @@ kern_return_t ForwardException(mach_port_t task, mach_port_t failed_thread,
|
||||||
|
|
||||||
mach_port_t target_port = current.ports[found];
|
mach_port_t target_port = current.ports[found];
|
||||||
exception_behavior_t target_behavior = current.behaviors[found];
|
exception_behavior_t target_behavior = current.behaviors[found];
|
||||||
thread_state_flavor_t target_flavor = current.flavors[found];
|
|
||||||
|
|
||||||
mach_msg_type_number_t thread_state_count = THREAD_STATE_MAX;
|
|
||||||
breakpad_thread_state_data_t thread_state;
|
|
||||||
kern_return_t result;
|
kern_return_t result;
|
||||||
switch (target_behavior) {
|
switch (target_behavior) {
|
||||||
case EXCEPTION_DEFAULT:
|
case EXCEPTION_DEFAULT:
|
||||||
|
@ -391,38 +436,8 @@ kern_return_t ForwardException(mach_port_t task, mach_port_t failed_thread,
|
||||||
code, code_count);
|
code, code_count);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXCEPTION_STATE:
|
|
||||||
result = thread_get_state(failed_thread, target_flavor, thread_state,
|
|
||||||
&thread_state_count);
|
|
||||||
if (result == KERN_SUCCESS)
|
|
||||||
result = exception_raise_state(target_port, failed_thread, task,
|
|
||||||
exception, code,
|
|
||||||
code_count, &target_flavor,
|
|
||||||
thread_state, thread_state_count,
|
|
||||||
thread_state, &thread_state_count);
|
|
||||||
if (result == KERN_SUCCESS)
|
|
||||||
result = thread_set_state(failed_thread, target_flavor, thread_state,
|
|
||||||
thread_state_count);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_STATE_IDENTITY:
|
|
||||||
result = thread_get_state(failed_thread, target_flavor, thread_state,
|
|
||||||
&thread_state_count);
|
|
||||||
if (result == KERN_SUCCESS)
|
|
||||||
result = exception_raise_state_identity(target_port, failed_thread,
|
|
||||||
task, exception, code,
|
|
||||||
code_count, &target_flavor,
|
|
||||||
thread_state,
|
|
||||||
thread_state_count,
|
|
||||||
thread_state,
|
|
||||||
&thread_state_count);
|
|
||||||
if (result == KERN_SUCCESS)
|
|
||||||
result = thread_set_state(failed_thread, target_flavor, thread_state,
|
|
||||||
thread_state_count);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "** Unknown exception behavior\n");
|
fprintf(stderr, "** Unknown exception behavior: %d\n", target_behavior);
|
||||||
result = KERN_FAILURE;
|
result = KERN_FAILURE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -430,18 +445,6 @@ kern_return_t ForwardException(mach_port_t task, mach_port_t failed_thread,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback from exc_server()
|
|
||||||
kern_return_t catch_exception_raise(mach_port_t port, mach_port_t failed_thread,
|
|
||||||
mach_port_t task,
|
|
||||||
exception_type_t exception,
|
|
||||||
exception_data_t code,
|
|
||||||
mach_msg_type_number_t code_count) {
|
|
||||||
if (task != mach_task_self()) {
|
|
||||||
return KERN_FAILURE;
|
|
||||||
}
|
|
||||||
return ForwardException(task, failed_thread, exception, code, code_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void *ExceptionHandler::WaitForMessage(void *exception_handler_class) {
|
void *ExceptionHandler::WaitForMessage(void *exception_handler_class) {
|
||||||
ExceptionHandler *self =
|
ExceptionHandler *self =
|
||||||
|
@ -561,7 +564,7 @@ void *ExceptionHandler::WaitForMessage(void *exception_handler_class) {
|
||||||
// message and call catch_exception_raise() and put the return
|
// message and call catch_exception_raise() and put the return
|
||||||
// code into the reply.
|
// code into the reply.
|
||||||
ExceptionReplyMessage reply;
|
ExceptionReplyMessage reply;
|
||||||
if (!exc_server(&receive.header, &reply.header))
|
if (!breakpad_exc_server(&receive.header, &reply.header))
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
// Send a reply and exit
|
// Send a reply and exit
|
||||||
|
|
Loading…
Reference in a new issue