From 72ddd4d8cb81725e8617bf96cd1ede9a05c283c2 Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Thu, 12 Dec 2024 21:43:24 +0000 Subject: [PATCH] Fixes an issue where errors do not get propogated correctly when the hypervisor handler thread returns an error. The hypervisor handler thread can return an error rather than send a message, in this case the error returned would be a timeout rather than the real error, this change ensures that we check for an error in the hypervisor handler thread when we time out and return that if it exists Signed-off-by: Simon Davies --- .../src/hypervisor/hypervisor_handler.rs | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/hyperlight_host/src/hypervisor/hypervisor_handler.rs b/src/hyperlight_host/src/hypervisor/hypervisor_handler.rs index 8e1645cb..96b6e899 100644 --- a/src/hyperlight_host/src/hypervisor/hypervisor_handler.rs +++ b/src/hyperlight_host/src/hypervisor/hypervisor_handler.rs @@ -592,7 +592,29 @@ impl HypervisorHandler { HandlerMsg::Error(e) => Err(e), HandlerMsg::FinishedHypervisorHandlerAction => Ok(()), }, - Err(_) => Err(HyperlightError::HypervisorHandlerMessageReceiveTimedout()), + Err(_) => { + // If we have timed out it may be that the handler thread returned an error before it sent a message, so rather than just timeout here + // we will try and get the join handle for the thread and if it has finished check to see if it returned an error + // if it did then we will return that error, otherwise we will return the timeout error + // we need to take ownership of the handle to join it + match self + .execution_variables + .join_handle + .try_lock() + .map_err(|_| HyperlightError::HypervisorHandlerMessageReceiveTimedout())? + .take_if(|handle| handle.is_finished()) + { + Some(handle) => { + // If the thread has finished, we try to join it and return the error if it has one + let res = handle.join(); + if res.as_ref().is_ok_and(|inner_res| inner_res.is_err()) { + return Err(res.unwrap().unwrap_err()); + } + Err(HyperlightError::HypervisorHandlerMessageReceiveTimedout()) + } + None => Err(HyperlightError::HypervisorHandlerMessageReceiveTimedout()), + } + } } }