diff --git a/vm/callstack.cpp b/vm/callstack.cpp index ce4d242119..f2ad5096c8 100755 --- a/vm/callstack.cpp +++ b/vm/callstack.cpp @@ -24,19 +24,30 @@ void factor_vm::dispatch_signal_handler(cell *sp, cell *pc, cell newpc) that don't create a stack frame will be out of alignment by sizeof(cell) bytes. */ cell offset = *sp % 16; - if (offset != 0) - fatal_error("fault in unaligned frame at", *pc); - - /* Nonleaf procedure */ - cell newsp = *sp - sizeof(cell); - *sp = newsp; - *(cell*)newsp = *pc; - *pc = newpc; - ctx->callstack_top = (stack_frame*)newsp; - - /* XXX handle leaf procedure */ + if (offset == 0) { + signal_from_leaf = false; + cell newsp = *sp - sizeof(cell); + *sp = newsp; + *(cell*)newsp = *pc; + *pc = newpc; + ctx->callstack_top = (stack_frame*)newsp; + } else if (offset == 16 - sizeof(cell)) { + dispatch_signal_handler_from_leaf(sp, pc, newpc); + } else { + fatal_error("Invalid stack frame during signal handler", *sp); + } } +void factor_vm::dispatch_signal_handler_from_leaf(cell *sp, cell *pc, cell newpc) +{ + /* We should try to conjure a stack frame here, but we may need to deal + with callstack overflows or the GC moving code around. + For now leave the stack untouched so the signal handler returns into + the parent procedure. This will cause things to blow up if the stack + is left unbalanced. */ + signal_from_leaf = true; + *pc = newpc; +} /* We ignore the two topmost frames, the 'callstack' primitive frame itself, and the frame calling the 'callstack' primitive, diff --git a/vm/errors.cpp b/vm/errors.cpp index c57e7832f7..1b5fe221f1 100755 --- a/vm/errors.cpp +++ b/vm/errors.cpp @@ -179,9 +179,11 @@ void factor_vm::enqueue_safepoint_sample() void factor_vm::handle_safepoint() { + if (signal_from_leaf) + std::cout << "XXX SIGNALED FROM LEAF\n"; + if (safepoint_fep) { - std::cout << "Interrupted. Entering low-level debugger...\n"; - std::cout << "\n"; + std::cout << "Interrupted\n"; factorbug(); code->unguard_safepoint(); safepoint_fep = false; diff --git a/vm/vm.hpp b/vm/vm.hpp index b7373b3951..180b92b3c5 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -56,6 +56,7 @@ struct factor_vm /* Global variables used to pass fault handler state from signal handler to VM */ + bool signal_from_leaf; cell signal_number; cell signal_fault_addr; unsigned int signal_fpu_status; @@ -605,6 +606,7 @@ struct factor_vm void primitive_callstack_bounds(); template void iterate_callstack(context *ctx, Iterator &iterator); void dispatch_signal_handler(cell *sp, cell *pc, cell newpc); + void dispatch_signal_handler_from_leaf(cell *sp, cell *pc, cell newpc); template void dispatch_signal_handler(CellA *sp, CellB *pc, CellC newpc)