@@ -28,6 +28,14 @@ macro_rules! guest_fault_common_defs {
2828 123
2929 }
3030
31+ pub struct OtherPanicPayload ;
32+
33+ #[ lucet_hostcall]
34+ #[ no_mangle]
35+ pub fn raise_other_panic( _vmctx: & Vmctx ) {
36+ panic!( OtherPanicPayload ) ;
37+ }
38+
3139 pub static mut RECOVERABLE_PTR : * mut libc:: c_char = std:: ptr:: null_mut( ) ;
3240
3341 #[ no_mangle]
@@ -55,6 +63,17 @@ macro_rules! guest_fault_common_defs {
5563 }
5664 }
5765
66+ extern "C" fn raise_other_panic_main( vmctx: * const lucet_vmctx) {
67+ extern "C" {
68+ // actually is defined in this file
69+ fn raise_other_panic( vmctx: * const lucet_vmctx) ;
70+ }
71+ unsafe {
72+ raise_other_panic( vmctx) ;
73+ std:: hint:: unreachable_unchecked( ) ;
74+ }
75+ }
76+
5877 extern "C" fn infinite_loop( _vmctx: * const lucet_vmctx) {
5978 loop { }
6079 }
@@ -156,6 +175,10 @@ macro_rules! guest_fault_common_defs {
156175 "hostcall_main" ,
157176 FunctionPointer :: from_usize( hostcall_main as usize ) ,
158177 ) )
178+ . with_export_func( MockExportBuilder :: new(
179+ "raise_other_panic_main" ,
180+ FunctionPointer :: from_usize( raise_other_panic_main as usize ) ,
181+ ) )
159182 . with_export_func( MockExportBuilder :: new(
160183 "infinite_loop" ,
161184 FunctionPointer :: from_usize( infinite_loop as usize ) ,
@@ -622,7 +645,8 @@ macro_rules! guest_fault_tests {
622645 test_nonex( || {
623646 let module = mock_traps_module( ) ;
624647 let region =
625- <TestRegion as RegionCreate >:: create( 1 , & Limits :: default ( ) ) . expect( "region can be created" ) ;
648+ <TestRegion as RegionCreate >:: create( 1 , & Limits :: default ( ) )
649+ . expect( "region can be created" ) ;
626650 let mut inst = region
627651 . new_instance( module)
628652 . expect( "instance can be created" ) ;
@@ -648,6 +672,32 @@ macro_rules! guest_fault_tests {
648672 } ) ;
649673 }
650674
675+ #[ test]
676+ fn raise_other_panic( ) {
677+ test_nonex( || {
678+ let module = mock_traps_module( ) ;
679+ let region =
680+ <TestRegion as RegionCreate >:: create( 1 , & Limits :: default ( ) )
681+ . expect( "region can be created" ) ;
682+ let mut inst = region
683+ . new_instance( module)
684+ . expect( "instance can be created" ) ;
685+
686+ match inst. run( "raise_other_panic_main" , & [ ] ) {
687+ Err ( Error :: RuntimeTerminated ( TerminationDetails :: OtherPanic ( payload) ) ) => {
688+ assert!( payload. is:: <crate :: common:: OtherPanicPayload >( ) ) ;
689+ }
690+ res => panic!( "unexpected result: {:?}" , res) ,
691+ }
692+
693+ // after a fault, can reset and run a normal function; in practice we would
694+ // want to reraise the panic most of the time, but this should still work
695+ inst. reset( ) . expect( "instance resets" ) ;
696+
697+ run_onetwothree( & mut inst) ;
698+ } ) ;
699+ }
700+
651701 #[ test]
652702 fn fatal_continue_signal_handler( ) {
653703 fn signal_handler_continue(
0 commit comments