keep a map of thread ids to vm pointers. use this to look up the correct VM to handle mach exceptions on os x
parent
f867a776d9
commit
435cd02200
|
@ -4,6 +4,7 @@ namespace factor
|
|||
{
|
||||
|
||||
factor_vm *vm;
|
||||
unordered_map<THREADHANDLE, factor_vm*> thread_vms;
|
||||
|
||||
void init_globals()
|
||||
{
|
||||
|
@ -46,7 +47,7 @@ void factor_vm::default_parameters(vm_parameters *p)
|
|||
#else
|
||||
if (this == vm)
|
||||
p->console = true;
|
||||
else
|
||||
else
|
||||
p->console = false;
|
||||
|
||||
#endif
|
||||
|
@ -221,23 +222,30 @@ struct startargs {
|
|||
vm_char **argv;
|
||||
};
|
||||
|
||||
// arg must be new'ed because we're going to delete it!
|
||||
void* start_standalone_factor_thread(void *arg)
|
||||
factor_vm * new_factor_vm()
|
||||
{
|
||||
factor_vm *newvm = new factor_vm;
|
||||
register_vm_with_thread(newvm);
|
||||
thread_vms[thread_id()] = newvm;
|
||||
|
||||
return newvm;
|
||||
}
|
||||
|
||||
// arg must be new'ed because we're going to delete it!
|
||||
void* start_standalone_factor_thread(void *arg)
|
||||
{
|
||||
factor_vm *newvm = new_factor_vm();
|
||||
startargs *args = (startargs*) arg;
|
||||
int argc = args->argc; vm_char **argv = args->argv;
|
||||
delete args;
|
||||
int argc = args->argc; vm_char **argv = args->argv;
|
||||
delete args;
|
||||
newvm->start_standalone_factor(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
VM_C_API void start_standalone_factor(int argc, vm_char **argv)
|
||||
{
|
||||
factor_vm *newvm = new factor_vm;
|
||||
factor_vm *newvm = new_factor_vm();
|
||||
vm = newvm;
|
||||
register_vm_with_thread(newvm);
|
||||
return newvm->start_standalone_factor(argc,argv);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ void factor_vm::call_fault_handler(
|
|||
exception_data_type_t code,
|
||||
MACH_EXC_STATE_TYPE *exc_state,
|
||||
MACH_THREAD_STATE_TYPE *thread_state,
|
||||
MACH_FLOAT_STATE_TYPE *float_state)
|
||||
MACH_FLOAT_STATE_TYPE *float_state)
|
||||
{
|
||||
/* There is a race condition here, but in practice an exception
|
||||
delivered during stack frame setup/teardown or while transitioning
|
||||
|
@ -68,17 +68,23 @@ void factor_vm::call_fault_handler(
|
|||
}
|
||||
}
|
||||
|
||||
static void call_fault_handler(exception_type_t exception,
|
||||
static void call_fault_handler(
|
||||
mach_port_t thread,
|
||||
exception_type_t exception,
|
||||
exception_data_type_t code,
|
||||
MACH_EXC_STATE_TYPE *exc_state,
|
||||
MACH_THREAD_STATE_TYPE *thread_state,
|
||||
MACH_FLOAT_STATE_TYPE *float_state)
|
||||
{
|
||||
SIGNAL_VM_PTR()->call_fault_handler(exception,code,exc_state,thread_state,float_state);
|
||||
THREADHANDLE thread_id = pthread_from_mach_thread_np(thread);
|
||||
assert(thread_id);
|
||||
unordered_map<THREADHANDLE, factor_vm*>::const_iterator vm = thread_vms.find(thread_id);
|
||||
if (vm != thread_vms.end())
|
||||
vm->second->call_fault_handler(exception,code,exc_state,thread_state,float_state);
|
||||
}
|
||||
|
||||
/* Handle an exception by invoking the user's fault handler and/or forwarding
|
||||
the duty to the previously installed handlers. */
|
||||
the duty to the previously installed handlers. */
|
||||
extern "C"
|
||||
kern_return_t
|
||||
catch_exception_raise (mach_port_t exception_port,
|
||||
|
@ -95,7 +101,7 @@ catch_exception_raise (mach_port_t exception_port,
|
|||
|
||||
/* Get fault information and the faulting thread's register contents..
|
||||
|
||||
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/thread_get_state.html. */
|
||||
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/thread_get_state.html. */
|
||||
exc_state_count = MACH_EXC_STATE_COUNT;
|
||||
if (thread_get_state (thread, MACH_EXC_STATE_FLAVOR,
|
||||
(natural_t *)&exc_state, &exc_state_count)
|
||||
|
@ -116,7 +122,7 @@ catch_exception_raise (mach_port_t exception_port,
|
|||
return KERN_FAILURE;
|
||||
}
|
||||
|
||||
float_state_count = MACH_FLOAT_STATE_COUNT;
|
||||
float_state_count = MACH_FLOAT_STATE_COUNT;
|
||||
if (thread_get_state (thread, MACH_FLOAT_STATE_FLAVOR,
|
||||
(natural_t *)&float_state, &float_state_count)
|
||||
!= KERN_SUCCESS)
|
||||
|
@ -128,11 +134,11 @@ catch_exception_raise (mach_port_t exception_port,
|
|||
|
||||
/* Modify registers so to have the thread resume executing the
|
||||
fault handler */
|
||||
call_fault_handler(exception,code[0],&exc_state,&thread_state,&float_state);
|
||||
call_fault_handler(thread,exception,code[0],&exc_state,&thread_state,&float_state);
|
||||
|
||||
/* Set the faulting thread's register contents..
|
||||
|
||||
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/thread_set_state.html. */
|
||||
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/thread_set_state.html. */
|
||||
if (thread_set_state (thread, MACH_FLOAT_STATE_FLAVOR,
|
||||
(natural_t *)&float_state, float_state_count)
|
||||
!= KERN_SUCCESS)
|
||||
|
@ -167,7 +173,7 @@ mach_exception_thread (void *arg)
|
|||
char data[1024];
|
||||
}
|
||||
msg;
|
||||
/* Buffer for a reply message. */
|
||||
/* Buffer for a reply message. */
|
||||
struct
|
||||
{
|
||||
mach_msg_header_t head;
|
||||
|
@ -230,7 +236,7 @@ void mach_initialize ()
|
|||
for a particular thread. This has the effect that when our exception
|
||||
port gets the message, the thread specific exception port has already
|
||||
been asked, and we don't need to bother about it.
|
||||
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_set_exception_ports.html. */
|
||||
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_set_exception_ports.html. */
|
||||
if (task_set_exception_ports (self, mask, our_exception_port,
|
||||
EXCEPTION_DEFAULT, MACHINE_THREAD_STATE)
|
||||
!= KERN_SUCCESS)
|
||||
|
|
|
@ -45,7 +45,7 @@ typedef char symbol_char;
|
|||
typedef pthread_t THREADHANDLE;
|
||||
|
||||
THREADHANDLE start_thread(void *(*start_routine)(void *),void *args);
|
||||
pthread_t thread_id();
|
||||
inline static THREADHANDLE thread_id() { return pthread_self(); }
|
||||
|
||||
void unix_init_signals();
|
||||
void signal_handler(int signal, siginfo_t* siginfo, void* uap);
|
||||
|
|
|
@ -29,6 +29,7 @@ FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe);
|
|||
typedef HANDLE THREADHANDLE;
|
||||
|
||||
THREADHANDLE start_thread(void *(*start_routine)(void *),void *args);
|
||||
inline static THREADHANDLE thread_id() { return GetCurrentThread(); }
|
||||
|
||||
void init_platform_globals();
|
||||
struct factor_vm;
|
||||
|
|
Loading…
Reference in New Issue