@@ -1050,6 +1050,7 @@ fn interrupt_random_kill_stress_test() {
10501050 let sandbox_wrapper = guard. sandbox_with_snapshot . as_mut ( ) . unwrap ( ) ;
10511051 let sandbox = & mut sandbox_wrapper. sandbox ;
10521052 let interrupt_handle = sandbox. interrupt_handle ( ) ;
1053+ let watchdog_handle = interrupt_handle. clone ( ) ;
10531054
10541055 // If we decided to kill, spawn a thread that will kill at a random time
10551056 // Use a barrier to ensure the killer thread waits until we're about to call the guest
@@ -1110,7 +1111,26 @@ fn interrupt_random_kill_stress_test() {
11101111 ) ;
11111112 }
11121113
1114+ // Watchdog: if the guest call doesn't return within 30s,
1115+ // force-kill it and print diagnostics.
1116+ let watchdog_thread_id = thread_id;
1117+ let watchdog_iteration = iteration;
1118+ let watchdog_should_kill = should_kill;
1119+ let watchdog = thread:: spawn ( move || {
1120+ thread:: sleep ( Duration :: from_secs ( 30 ) ) ;
1121+ println ! (
1122+ "WATCHDOG: Thread {} iteration {} HUNG for 30s (should_kill={}), force-killing" ,
1123+ watchdog_thread_id, watchdog_iteration, watchdog_should_kill
1124+ ) ;
1125+ watchdog_handle. kill ( ) ;
1126+ } ) ;
1127+
11131128 let result = sandbox. call :: < u64 > ( "SpinForMs" , GUEST_CALL_DURATION_MS ) ;
1129+
1130+ // Cancel the watchdog (it will exit on its own but we don't
1131+ // need to join it — it's a daemon-style thread that only
1132+ // fires if the call hangs)
1133+ drop ( watchdog) ;
11141134 trace ! (
11151135 "[THREAD-{}] Iteration {}: Guest call returned: {:?}" ,
11161136 thread_id,
0 commit comments