WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

Commit cf60ddf1 authored by Isaac Oscar Gariano's avatar Isaac Oscar Gariano
Browse files

Added better debug info for exception handling

parent 7c9c215b
......@@ -39,7 +39,7 @@ use runtime::*;
/// real frame pointers or the frame cursor)
#[no_mangle]
pub extern "C" fn throw_exception_internal(exception_obj: Address, frame_cursor: Address) -> ! {
trace!("throwing exception: {}", exception_obj);
debug!("throwing exception: {}", exception_obj);
if cfg!(debug_assertions) {
trace!("Initial Frame: ");
......@@ -65,7 +65,10 @@ pub extern "C" fn throw_exception_internal(exception_obj: Address, frame_cursor:
// acquire lock for exception table
let compiled_callsite_table = vm.compiled_callsite_table().read().unwrap();
/// TODO: This may segfault (but only in the case where their is a native frame...
print_backtrace(frame_cursor, compiled_callsite_table.deref());
loop {
// Lookup the table for the callsite
trace!("Callsite: 0x{:x}", callsite);
trace!("\tprevious_frame_pointer: 0x{:x}", previous_frame_pointer);
......@@ -82,8 +85,6 @@ pub extern "C" fn throw_exception_internal(exception_obj: Address, frame_cursor:
either there isn't a catch block to catch the exception or \
your catch block is above a native function call"
);
// This function may segfault
print_backtrace(frame_cursor, compiled_callsite_table.deref());
panic!("Uncaught Mu Exception");
}
table_entry.unwrap()
......@@ -92,7 +93,8 @@ pub extern "C" fn throw_exception_internal(exception_obj: Address, frame_cursor:
// Check for a catch block at this callsite
if callsite_info.exceptional_destination.is_some() {
catch_address = callsite_info.exceptional_destination.unwrap();
trace!("Found catch block: 0x{:x}", catch_address);
debug!("Found catch block: 0x{:x} - {}", catch_address,
get_symbol_name(catch_address));
sp = get_previous_stack_pointer(
current_frame_pointer,
callsite_info.stack_args_size
......@@ -155,7 +157,7 @@ fn print_frame(cursor: Address) {
/// This function may segfault or panic when it reaches the bottom of the stack
// TODO: Determine where the bottom is without segfaulting
fn print_backtrace(base: Address, compiled_callsite_table: &HashMap<Address, CompiledCallsite>) {
error!("BACKTRACE: ");
debug!("BACKTRACE: ");
let cur_thread = thread::MuThread::current();
let ref vm = cur_thread.vm;
......@@ -166,6 +168,10 @@ fn print_backtrace(base: Address, compiled_callsite_table: &HashMap<Address, Com
loop {
let callsite = get_return_address(frame_pointer);
frame_pointer = get_previous_frame_pointer(frame_pointer);
if frame_pointer.is_zero() {
return;
}
if compiled_callsite_table.contains_key(&callsite) {
let function_version = compiled_callsite_table
......@@ -178,18 +184,19 @@ fn print_backtrace(base: Address, compiled_callsite_table: &HashMap<Address, Com
.read()
.unwrap();
error!(
"\tframe {:2}: 0x{:x} - {} (fid: #{}, fvid: #{}) at 0x{:x}",
debug!(
"\tframe {:2}: 0x{:x} - {} (fid: #{}, fvid: #{}) at 0x{:x} - {}",
frame_count,
compiled_func.start.to_address(),
vm.get_name_for_func(compiled_func.func_id),
compiled_func.func_id,
compiled_func.func_ver_id,
callsite
callsite,
get_symbol_name(callsite)
);
} else {
let (func_name, func_start) = get_function_info(callsite);
error!(
debug!(
"\tframe {:2}: 0x{:x} - {} at 0x{:x}",
frame_count,
func_start,
......@@ -198,10 +205,6 @@ fn print_backtrace(base: Address, compiled_callsite_table: &HashMap<Address, Com
);
}
frame_pointer = get_previous_frame_pointer(frame_pointer);
if frame_pointer.is_zero() {
return;
}
frame_count += 1;
}
}
......@@ -45,6 +45,14 @@ pub mod exception;
lazy_static!{
static ref UNKNOWN_FUNCTION_NAME : CName = Arc::new("UNKOWN".to_string());
}
/// returns the name for a symbol address (inverse of resolve_symbol)
/// WARNING: Only use this for Mu symbols
pub fn get_symbol_name(symbol: Address) -> CName {
let (name, start) = get_function_info(symbol);
assert!(start == symbol);
return demangle_name((*name).clone());
}
/// returns name for a function address
// FIXME: this actually returns the name and address of the nearest symbol (of any type)
// that starts before function_addr (instead we want the nearest function symbol)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment