vm: clean up signal handler dispatch

Remove the weird and broken functions fix_callstack_top and scrub_return_address. Instead, simply decrement the SP and store the PC from the front end of the signal handler so that the back end can return back into the original context normally. Currently aborts for leaf procedure frames pending a more robust solution.
db4
Joe Groff 2011-10-20 20:55:55 -07:00
parent 92a5b7c300
commit 1dc31d133b
4 changed files with 11 additions and 28 deletions

View File

@ -18,22 +18,6 @@ callstack *factor_vm::allot_callstack(cell size)
return stack;
}
/* If 'stack' points into the middle of the frame, find the nearest valid stack
pointer where we can resume execution and hope to capture the call trace without
crashing. Also, make sure we have at least 'stack_reserved' bytes available so
that we don't run out of callstack space while handling the error. */
stack_frame *factor_vm::fix_callstack_top(stack_frame *stack)
{
stack_frame *frame = ctx->callstack_bottom - 1;
while(frame >= stack
&& frame >= ctx->callstack_top
&& (cell)frame >= ctx->callstack_seg->start + stack_reserved)
frame = frame_successor(frame);
return frame + 1;
}
/* We ignore the two topmost frames, the 'callstack' primitive
frame itself, and the frame calling the 'callstack' primitive,
so that set-callstack doesn't get stuck in an infinite loop.
@ -127,13 +111,6 @@ void factor_vm::set_frame_offset(stack_frame *frame, cell offset)
FRAME_RETURN_ADDRESS(frame,this) = entry_point + offset;
}
void factor_vm::scrub_return_address()
{
stack_frame *frame = innermost_stack_frame(ctx->callstack_bottom,
ctx->callstack_top);
set_frame_offset(frame,0);
}
cell factor_vm::frame_scan(stack_frame *frame)
{
switch(frame_type(frame))

View File

@ -125,7 +125,6 @@ void factor_vm::primitive_unimplemented()
void factor_vm::memory_signal_handler_impl()
{
scrub_return_address();
memory_protection_error(signal_fault_addr);
}
@ -136,7 +135,6 @@ void memory_signal_handler_impl()
void factor_vm::synchronous_signal_handler_impl()
{
scrub_return_address();
signal_error(signal_number);
}
@ -150,7 +148,6 @@ void factor_vm::fp_signal_handler_impl()
/* Clear pending exceptions to avoid getting stuck in a loop */
set_fpu_state(get_fpu_state());
scrub_return_address();
fp_trap_error(signal_fpu_status);
}

View File

@ -35,7 +35,11 @@ void factor_vm::call_fault_handler(
MACH_THREAD_STATE_TYPE *thread_state,
MACH_FLOAT_STATE_TYPE *float_state)
{
MACH_STACK_POINTER(thread_state) = (cell)fix_callstack_top((stack_frame *)MACH_STACK_POINTER(thread_state));
cell offset = MACH_STACK_POINTER(thread_state) % 16;
if (offset != 0)
fatal_error("fault in unaligned frame with offset", offset);
MACH_STACK_POINTER(thread_state) -= sizeof(cell);
*(cell*)MACH_STACK_POINTER(thread_state) = MACH_PROGRAM_COUNTER(thread_state);
ctx->callstack_top = (stack_frame *)MACH_STACK_POINTER(thread_state);

View File

@ -138,7 +138,12 @@ void code_heap::unguard_safepoint()
void factor_vm::dispatch_signal(void *uap, void (handler)())
{
UAP_STACK_POINTER(uap) = (UAP_STACK_POINTER_TYPE)fix_callstack_top((stack_frame *)UAP_STACK_POINTER(uap));
cell sp = (cell)UAP_STACK_POINTER(uap);
cell offset = sp % 16;
if (offset != 0)
fatal_error("fault in unaligned frame with offset", offset);
UAP_STACK_POINTER(uap) = (UAP_STACK_POINTER_TYPE)(sp - sizeof(cell));
*(cell*)(UAP_STACK_POINTER(uap)) = (cell)UAP_PROGRAM_COUNTER(uap);
UAP_PROGRAM_COUNTER(uap) = (cell)FUNCTION_CODE_POINTER(handler);
UAP_SET_TOC_POINTER(uap, (cell)FUNCTION_TOC_POINTER(handler));
ctx->callstack_top = (stack_frame *)UAP_STACK_POINTER(uap);