Catching SIGBUS in Mach exception handler
Catching SIGBUS in Mach exception handler
- Subject: Catching SIGBUS in Mach exception handler
- From: leenoori <email@hidden>
- Date: Tue, 24 Oct 2006 19:28:57 +0200
I want to catch SIGBUS signals and perform special handling in my
application. I originally tried this using signal() and sigaction()
but found that the Mac OS X crash reporter application popped up
informing me that my app had crashed even though it continued running
(a known issue; see: http://developer.apple.com/technotes/tn2004/
tn2123.html). A trick that I recall working in pre-Tiger days
(forking in the signal handler) no longer works.
So in an effort to stop the crash reporter from popping up I tried to
set my own Mach exception handler as shown in the code below. This is
a reduced demonstration case with all the error checking taken out
and extraneous lines removed. In this example I'm merely trying to
catch the signal and ignore it; once I get that working I'll
implement the actual special handling.
But it's not working... Basically, what happens as soon as the SIGBUS
is sent the code enters the catch_exception_raise() function. If I
return KERN_SUCCESS from that function then I find myself back in the
function again (and again and again in an infinite loop) which is not
what I would have expected from my reading of the man page:
http://www.opensource.apple.com/darwinsource/10.4/xnu-792/osfmk/man/
catch_exception_raise.html
"A return value of KERN_SUCCESS indicates that the thread is to
continue from the point of exception."
I interpret that to mean on the next instruction, the one after the
one that provoked the exception, but that doesn't seem to be
happening here...
So any ideas about what I'm doing wrong?
This is Objective-C so stick it in a file like "foo.m", run "cc -
framework Foundation foo.m -o foo" and then execute the binary.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <stdarg.h>
#include <pthread.h>
#include <assert.h>
#include <mach/mach.h>
kern_return_t
catch_exception_raise(mach_port_t exception_port,
mach_port_t thread,
mach_port_t task,
exception_type_t exception,
exception_data_t code_vector,
mach_msg_type_number_t code_count)
{
fprintf(stderr, "catch_exception_raise %d\n", exception);
return KERN_SUCCESS; // loops infinitely...
}
void *exception_handler(void *arg)
{
extern boolean_t exc_server();
mach_port_t port = (mach_port_t) arg;
mach_msg_server(exc_server, 2048, port, 0);
abort(); // without this GCC complains (it doesn't know that
mach_msg_server never returns)
}
void setup_mach_exception_port()
{
static mach_port_t exception_port = MACH_PORT_NULL;
mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
&exception_port);
mach_port_insert_right(mach_task_self(), exception_port,
exception_port, MACH_MSG_TYPE_MAKE_SEND);
task_set_exception_ports(mach_task_self(), EXC_MASK_BAD_ACCESS,
exception_port, EXCEPTION_DEFAULT, MACHINE_THREAD_STATE);
pthread_t returned_thread;
pthread_create(&returned_thread, NULL, exception_handler, (void*)
exception_port);
}
void test_crash()
{
id *obj = NULL;
*obj = @"foo";
}
int main(int argc, char** argv)
{
setup_mach_exception_port();
test_crash();
return 0;
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden