Skip to content

Commit b958211

Browse files
committed
[test] added test for exception handling
- added new guest fxn to simpleguest that triggers an invalid opcode exception - added test in guest_dispatch that calls the new guest fxn to test exception handling Signed-off-by: danbugs <[email protected]>
1 parent c3c8e3c commit b958211

File tree

3 files changed

+58
-11
lines changed

3 files changed

+58
-11
lines changed

src/hyperlight_host/src/func/guest_dispatch.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,4 +480,36 @@ mod tests {
480480
),
481481
}
482482
}
483+
484+
#[test]
485+
fn test_trigger_exception_on_guest() {
486+
let usbox = UninitializedSandbox::new(
487+
GuestBinary::FilePath(simple_guest_as_string().expect("Guest Binary Missing")),
488+
None,
489+
None,
490+
None,
491+
)
492+
.unwrap();
493+
494+
let mut multi_use_sandbox: MultiUseSandbox = usbox.evolve(Noop::default()).unwrap();
495+
496+
let res = multi_use_sandbox.call_guest_function_by_name(
497+
"TriggerException",
498+
ReturnType::Void,
499+
None,
500+
);
501+
502+
assert!(res.is_err());
503+
504+
match res.unwrap_err() {
505+
HyperlightError::GuestAborted(_, msg) => {
506+
// msg should indicate we got an invalid opcode exception
507+
assert!(msg.contains("EXCEPTION: 0x6"));
508+
}
509+
e => panic!(
510+
"Expected HyperlightError::GuestExecutionError but got {:?}",
511+
e
512+
),
513+
}
514+
}
483515
}

src/hyperlight_host/tests/integration_test.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ limitations under the License.
1717
use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode;
1818
use hyperlight_common::mem::PAGE_SIZE;
1919
use hyperlight_host::func::{ParameterValue, ReturnType, ReturnValue};
20-
#[cfg(not(feature = "executable_heap"))]
21-
use hyperlight_host::mem::memory_region::MemoryRegionFlags;
2220
use hyperlight_host::sandbox::SandboxConfiguration;
2321
use hyperlight_host::sandbox_state::sandbox::EvolvableSandbox;
2422
use hyperlight_host::sandbox_state::transition::Noop;
@@ -388,7 +386,10 @@ fn execute_on_stack() {
388386
.call_guest_function_by_name("ExecuteOnStack", ReturnType::String, Some(vec![]))
389387
.unwrap_err();
390388

391-
// TODO: because we set the stack as NX in the guest PTE we get a generic error, once we handle the exception correctly in the guest we can make this more specific
389+
// (Note) We do this because, currently:
390+
// - the C guest triggers a generic error, while
391+
// - the Rust guest triggers a proper exception.
392+
// TODO: figure out discrepancy between C and Rust guests here
392393
if let HyperlightError::Error(message) = result {
393394
cfg_if::cfg_if! {
394395
if #[cfg(target_os = "linux")] {
@@ -400,7 +401,11 @@ fn execute_on_stack() {
400401
}
401402
}
402403
} else {
403-
panic!("Unexpected error type");
404+
let err = result.to_string();
405+
assert!(
406+
// exception that indicates a page fault
407+
err.contains("EXCEPTION: 0xe")
408+
);
404409
}
405410
}
406411

@@ -419,13 +424,8 @@ fn execute_on_heap() {
419424
{
420425
assert!(result.is_err());
421426
let err = result.unwrap_err();
422-
assert!(
423-
matches!(
424-
err,
425-
HyperlightError::MemoryAccessViolation(_, MemoryRegionFlags::EXECUTE, _)
426-
) || matches!(err, HyperlightError::Error(ref s) if s.starts_with("Unexpected VM Exit"))
427-
|| matches!(err, HyperlightError::Error(ref s) if s.starts_with("unknown Hyper-V run message type")) // Because the memory is set as NX in the guest PTE we get a generic error, once we handle the exception correctly in the guest we can make this more specific
428-
);
427+
428+
assert!(err.to_string().contains("EXCEPTION: 0xe"));
429429
}
430430
}
431431

src/tests/rust_guests/simpleguest/src/main.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,13 @@ fn log_message(function_call: &FunctionCall) -> Result<Vec<u8>> {
637637
}
638638
}
639639

640+
fn trigger_exception(_: &FunctionCall) -> Result<Vec<u8>> {
641+
unsafe {
642+
core::arch::asm!("ud2");
643+
} // trigger an undefined instruction exception
644+
Ok(get_flatbuffer_result_from_void())
645+
}
646+
640647
static mut COUNTER: i32 = 0;
641648

642649
fn add_to_static(function_call: &FunctionCall) -> Result<Vec<u8>> {
@@ -1094,6 +1101,14 @@ pub extern "C" fn hyperlight_main() {
10941101
add as i64,
10951102
);
10961103
register_function(add_def);
1104+
1105+
let trigger_exception_def = GuestFunctionDefinition::new(
1106+
"TriggerException".to_string(),
1107+
Vec::new(),
1108+
ReturnType::Void,
1109+
trigger_exception as i64,
1110+
);
1111+
register_function(trigger_exception_def);
10971112
}
10981113

10991114
#[no_mangle]

0 commit comments

Comments
 (0)