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));
|
static_cast<void *>(exception_object));
|
||||||
int frame_count = 0;
|
int frame_count = 0;
|
||||||
|
|
||||||
|
unw_word_t prev_sp = 0x0;
|
||||||
// Walk each frame until we reach where search phase said to stop.
|
// Walk each frame until we reach where search phase said to stop.
|
||||||
while (true) {
|
while (true) {
|
||||||
// Ask libunwind to get next frame (skip over first which is
|
// 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_word_t sp;
|
||||||
unw_proc_info_t frameInfo;
|
unw_proc_info_t frameInfo;
|
||||||
__unw_get_reg(cursor, UNW_REG_SP, &sp);
|
__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) {
|
if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase2(ex_ojb=%p): __unw_get_proc_info "
|
"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();
|
let exception = &exception_info.exception.unwrap();
|
||||||
if search_phase {
|
if search_phase {
|
||||||
match eh_action {
|
match eh_action {
|
||||||
EHAction::None |
|
EHAction::None => return continue_unwind(exception_object, context),
|
||||||
EHAction::Cleanup(_) => 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(_) => {
|
EHAction::Catch(_) => {
|
||||||
// EHABI requires the personality routine to update the
|
// EHABI requires the personality routine to update the
|
||||||
// SP value in the barrier cache of the exception object.
|
// 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) -> ! {
|
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");
|
trace!("Trying to raise exception");
|
||||||
|
// FIXME: unsound transmute
|
||||||
|
// This would cause stack memory corruption.
|
||||||
INFLIGHT.exception = Some(mem::transmute::<Exception, Exception<'static>>(*exception));
|
INFLIGHT.exception = Some(mem::transmute::<Exception, Exception<'static>>(*exception));
|
||||||
INFLIGHT.handled = false;
|
INFLIGHT.handled = false;
|
||||||
|
|
||||||
@ -219,9 +225,8 @@ pub unsafe extern fn raise(exception: *const Exception) -> ! {
|
|||||||
pub unsafe extern fn reraise() -> ! {
|
pub unsafe extern fn reraise() -> ! {
|
||||||
use cslice::AsCSlice;
|
use cslice::AsCSlice;
|
||||||
|
|
||||||
trace!("Re-raise");
|
// Reraise is basically cxa_rethrow, which calls _Unwind_Resume_or_Rethrow,
|
||||||
// current implementation uses raise as _Unwind_Resume is not working now
|
// which for EHABI would always call _Unwind_RaiseException.
|
||||||
// would debug that later.
|
|
||||||
match INFLIGHT.exception {
|
match INFLIGHT.exception {
|
||||||
Some(ref exception) => raise(exception),
|
Some(ref exception) => raise(exception),
|
||||||
None => raise(&Exception {
|
None => raise(&Exception {
|
||||||
|
Loading…
Reference in New Issue
Block a user