Skip to content

Commit bcb9246

Browse files
committed
[host/{hypervisor/{*drivers,crashdump},sandbox/builder}] re-added crashdump feature
Crashdump feature used the old MemoryRegion API. Updated it to use the new SandboxMemorySections API (causing changes in all drivers) and added a test in sandbox_builder for the feature. Signed-off-by: danbugs <[email protected]>
1 parent 9401bb2 commit bcb9246

File tree

7 files changed

+82
-22
lines changed

7 files changed

+82
-22
lines changed

src/hyperlight_host/src/hypervisor/crashdump.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ pub(crate) fn crashdump_to_tempfile(hv: &dyn Hypervisor) -> Result<()> {
1616
temp_file.write_all(b"================ MEMORY DUMP =================\n")?;
1717

1818
// write the raw memory dump for each memory region
19-
for region in hv.get_memory_regions() {
20-
if region.host_region.start == 0 || region.host_region.is_empty() {
19+
for (_, region) in hv.get_memory_sections().iter() {
20+
if region.page_aligned_guest_offset == 0 {
2121
continue;
2222
}
2323
// SAFETY: we got this memory region from the hypervisor so should never be invalid
2424
let region_slice = unsafe {
2525
std::slice::from_raw_parts(
26-
region.host_region.start as *const u8,
27-
region.host_region.len(),
26+
region.host_address.ok_or("Failed to get host address")? as *const u8,
27+
region.page_aligned_size,
2828
)
2929
};
3030
temp_file.write_all(region_slice)?;

src/hyperlight_host/src/hypervisor/hyperv_linux.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -658,11 +658,10 @@ impl Hypervisor for HypervLinuxDriver {
658658
self as &mut dyn Hypervisor
659659
}
660660

661-
// TODO(danbugs:297): bring back
662-
// #[cfg(crashdump)]
663-
// fn get_memory_regions(&self) -> &[MemoryRegion] {
664-
// &self.mem_sections
665-
// }
661+
#[cfg(crashdump)]
662+
fn get_memory_sections(&self) -> &SandboxMemorySections {
663+
&self.mem_sections
664+
}
666665

667666
#[cfg(gdb)]
668667
fn handle_debug(

src/hyperlight_host/src/hypervisor/hyperv_windows.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ impl Hypervisor for HypervWindowsDriver {
488488
}
489489

490490
#[cfg(crashdump)]
491-
fn get_memory_regions(&self) -> &[MemoryRegion] {
491+
fn get_memory_sections(&self) -> &SandboxMemorySections {
492492
&self.mem_sections
493493
}
494494
}

src/hyperlight_host/src/hypervisor/inprocess.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ use log::LevelFilter;
2222
#[cfg(gdb)]
2323
use super::handlers::DbgMemAccessHandlerWrapper;
2424
use super::{HyperlightExit, Hypervisor};
25-
#[cfg(crashdump)]
26-
use crate::mem::memory_region::MemoryRegion;
2725
use crate::sandbox::leaked_outb::LeakedOutBWrapper;
26+
#[cfg(crashdump)]
27+
use crate::sandbox::sandbox_builder::SandboxMemorySections;
2828
use crate::Result;
2929

3030
/// Arguments passed to inprocess driver
@@ -128,7 +128,7 @@ impl<'a> Hypervisor for InprocessDriver<'a> {
128128
}
129129

130130
#[cfg(crashdump)]
131-
fn get_memory_regions(&self) -> &[MemoryRegion] {
132-
unimplemented!("get_memory_regions is not supported since we are in in-process mode")
131+
fn get_memory_sections(&self) -> &SandboxMemorySections {
132+
unimplemented!("get_memory_sections is not supported since we are in in-process mode")
133133
}
134134
}

src/hyperlight_host/src/hypervisor/kvm.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -583,11 +583,10 @@ impl Hypervisor for KVMDriver {
583583
self as &mut dyn Hypervisor
584584
}
585585

586-
// TODO(danbugs:297): bring back
587-
// #[cfg(crashdump)]
588-
// fn get_memory_regions(&self) -> &[MemoryRegion] {
589-
// &self.mem_sections
590-
// }
586+
#[cfg(crashdump)]
587+
fn get_memory_sections(&self) -> &SandboxMemorySections {
588+
&self.mem_sections
589+
}
591590

592591
#[cfg(gdb)]
593592
fn handle_debug(

src/hyperlight_host/src/hypervisor/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,8 @@ pub(crate) trait Hypervisor: Debug + Sync + Send {
235235
#[cfg(target_os = "windows")]
236236
fn get_partition_handle(&self) -> windows::Win32::System::Hypervisor::WHV_PARTITION_HANDLE;
237237

238-
// TODO(danbugs:297): bring back
239-
// #[cfg(crashdump)]
240-
// fn get_memory_regions(&self) -> &[MemoryRegion];
238+
#[cfg(crashdump)]
239+
fn get_memory_sections(&self) -> &SandboxMemorySections;
241240

242241
#[cfg(gdb)]
243242
/// handles the cases when the vCPU stops due to a Debug event

src/hyperlight_host/src/sandbox/sandbox_builder.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,4 +957,67 @@ mod tests {
957957

958958
Ok(())
959959
}
960+
961+
#[test]
962+
#[cfg(crashdump)]
963+
fn test_sandbox_builder_crashdump() -> Result<()> {
964+
// Capture list of files in /tmp before the test
965+
let tmp_dir = Path::new("/tmp");
966+
let before_files: std::collections::HashSet<_> = std::fs::read_dir(tmp_dir)
967+
.expect("Failed to read /tmp directory")
968+
.map(|e| e.unwrap().file_name())
969+
.collect();
970+
971+
// Setup guest sandbox
972+
let sandbox_builder =
973+
SandboxBuilder::new(GuestBinary::FilePath(simple_guest_as_string()?))?;
974+
975+
let mut uninitialized_sandbox = sandbox_builder.build()?;
976+
977+
// Register host function
978+
fn add(a: i32, b: i32) -> Result<i32> {
979+
Ok(a + b)
980+
}
981+
let host_function = Arc::new(Mutex::new(add));
982+
host_function.register(&mut uninitialized_sandbox, "HostAdd")?;
983+
984+
// Evolve to multi-use sandbox
985+
let mut multi_use_sandbox = uninitialized_sandbox.evolve(Noop::default())?;
986+
987+
// Call the guest function expected to crash
988+
let result = multi_use_sandbox.call_guest_function_by_name(
989+
"StackOverflow",
990+
ReturnType::Void,
991+
Some(vec![ParameterValue::Int(512)]),
992+
);
993+
994+
assert!(result.is_err());
995+
996+
// Capture list of files in /tmp after the crash
997+
let after_files: std::collections::HashSet<_> = std::fs::read_dir(tmp_dir)
998+
.expect("Failed to read /tmp directory")
999+
.map(|e| e.unwrap().file_name())
1000+
.collect();
1001+
1002+
// Find the new files created
1003+
let new_files: Vec<_> = after_files
1004+
.difference(&before_files)
1005+
.filter(|f| f.to_string_lossy().ends_with(".dmp"))
1006+
.collect();
1007+
1008+
assert!(!new_files.is_empty(), "No crashdump file was created.");
1009+
1010+
// Check the crashdump file(s)
1011+
for file_name in new_files {
1012+
let file_path = tmp_dir.join(file_name);
1013+
let metadata = std::fs::metadata(&file_path)?;
1014+
assert!(
1015+
metadata.len() > 0,
1016+
"Crashdump file is empty: {:?}",
1017+
file_path
1018+
);
1019+
}
1020+
1021+
Ok(())
1022+
}
9601023
}

0 commit comments

Comments
 (0)