Kernel exception: fixed top level finally. (#70) #71
@ -551,6 +551,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor
|
||||
static_cast<void *>(exception_object));
|
||||
int frame_count = 0;
|
||||
|
||||
unw_word_t prev_sp = 0x0;
|
||||
// Walk each frame until we reach where search phase said to stop.
|
||||
while (true) {
|
||||
// Ask libunwind to get next frame (skip over first which is
|
||||
@ -576,6 +577,10 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor
|
||||
unw_word_t sp;
|
||||
unw_proc_info_t frameInfo;
|
||||
__unw_get_reg(cursor, UNW_REG_SP, &sp);
|
||||
if (sp == prev_sp) {
|
||||
return _URC_END_OF_STACK;
|
||||
}
|
||||
prev_sp = sp;
|
||||
if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
|
||||
_LIBUNWIND_TRACE_UNWINDING(
|
||||
"unwind_phase2(ex_ojb=%p): __unw_get_proc_info "
|
||||
|
@ -128,8 +128,15 @@ pub unsafe fn artiq_personality(state: uw::_Unwind_State,
|
||||
let exception = &exception_info.exception.unwrap();
|
||||
if search_phase {
|
||||
match eh_action {
|
||||
EHAction::None |
|
||||
EHAction::Cleanup(_) => return continue_unwind(exception_object, context),
|
||||
EHAction::None => return continue_unwind(exception_object, context),
|
||||
// Actually, cleanup should not return handler found, this is to workaround
|
||||
// the issue of terminating directly when no catch cause is found while
|
||||
// having some cleanup routines defined by finally.
|
||||
// The best way to handle this is to force unwind the stack in the raise
|
||||
// function when end of stack is reached, and call terminate at the end of
|
||||
// the unwind. Unfortunately, there is no forced unwind function defined
|
||||
// for EHABI, and I have no idea how to implement that, so this is a hack.
|
||||
EHAction::Cleanup(_) => return uw::_URC_HANDLER_FOUND,
|
||||
EHAction::Catch(_) => {
|
||||
// EHABI requires the personality routine to update the
|
||||
// SP value in the barrier cache of the exception object.
|
||||
@ -195,10 +202,9 @@ static mut INFLIGHT: ExceptionInfo = ExceptionInfo {
|
||||
};
|
||||
|
||||
pub unsafe extern fn raise(exception: *const Exception) -> ! {
|
||||
// Zing! The Exception<'a> to Exception<'static> transmute is not really sound in case
|
||||
// the exception is ever captured. Fortunately, they currently aren't, and we save
|
||||
// on the hassle of having to allocate exceptions somewhere except on stack.
|
||||
trace!("Trying to raise exception");
|
||||
// FIXME: unsound transmute
|
||||
// This would cause stack memory corruption.
|
||||
INFLIGHT.exception = Some(mem::transmute::<Exception, Exception<'static>>(*exception));
|
||||
INFLIGHT.handled = false;
|
||||
|
||||
@ -219,9 +225,8 @@ pub unsafe extern fn raise(exception: *const Exception) -> ! {
|
||||
pub unsafe extern fn reraise() -> ! {
|
||||
use cslice::AsCSlice;
|
||||
|
||||
trace!("Re-raise");
|
||||
// current implementation uses raise as _Unwind_Resume is not working now
|
||||
// would debug that later.
|
||||
// Reraise is basically cxa_rethrow, which calls _Unwind_Resume_or_Rethrow,
|
||||
// which for EHABI would always call _Unwind_RaiseException.
|
||||
match INFLIGHT.exception {
|
||||
Some(ref exception) => raise(exception),
|
||||
None => raise(&Exception {
|
||||
|
Loading…
Reference in New Issue
Block a user