@@ -55,6 +55,9 @@ pub(crate) mod windows_hypervisor_platform;
55
55
#[ cfg( target_os = "windows" ) ]
56
56
pub ( crate ) mod wrappers;
57
57
58
+ #[ cfg( crashdump) ]
59
+ pub ( crate ) mod crashdump;
60
+
58
61
use std:: fmt:: Debug ;
59
62
use std:: sync:: { Arc , Mutex } ;
60
63
@@ -184,70 +187,8 @@ pub(crate) trait Hypervisor: Debug + Sync + Send {
184
187
#[ cfg( target_os = "windows" ) ]
185
188
fn get_partition_handle ( & self ) -> windows:: Win32 :: System :: Hypervisor :: WHV_PARTITION_HANDLE ;
186
189
187
- /// Dump memory to a file on crash
188
- #[ cfg( all( debug_assertions, feature = "dump_on_crash" , target_os = "linux" ) ) ]
189
- fn dump_on_crash ( & self , mem_regions : Vec < MemoryRegion > ) {
190
- let memory_size = mem_regions
191
- . iter ( )
192
- . map ( |region| region. guest_region . end - region. guest_region . start )
193
- . sum ( ) ;
194
- if let Err ( e) = unsafe {
195
- self . write_dump_file (
196
- mem_regions. clone ( ) ,
197
- mem_regions[ 0 ] . host_region . start as * const u8 ,
198
- memory_size,
199
- )
200
- } {
201
- println ! ( "Error dumping memory: {}" , e) ;
202
- }
203
- }
204
-
205
- /// A function that takes an address and a size and writes the memory at that address to a file in the temp/tmp directory
206
- /// # Safety
207
- /// This function is unsafe because it is writing memory to a file, make sure that the address is valid and that the size is correct
208
- /// This function is only available when the `dump_on_crash` feature is enabled and running in debug mode
209
- #[ cfg( all( feature = "dump_on_crash" , debug_assertions) ) ]
210
- unsafe fn write_dump_file (
211
- & self ,
212
- regions : Vec < MemoryRegion > ,
213
- address : * const u8 ,
214
- size : usize ,
215
- ) -> Result < ( ) > {
216
- use std:: io:: Write ;
217
-
218
- use tempfile:: NamedTempFile ;
219
-
220
- if address. is_null ( ) || size == 0 {
221
- return Err ( new_error ! ( "Invalid address or size" ) ) ;
222
- }
223
-
224
- let hv_details = format ! ( "{:#?}" , self ) ;
225
- let regions_details = format ! ( "{:#?}" , regions) ;
226
-
227
- // Create a temporary file
228
- let mut file = NamedTempFile :: with_prefix ( "mem" ) ?;
229
- let temp_path = file. path ( ) . to_path_buf ( ) ;
230
-
231
- file. write_all ( hv_details. as_bytes ( ) ) ?;
232
- file. write_all ( b"\n " ) ?;
233
- file. write_all ( regions_details. as_bytes ( ) ) ?;
234
- file. write_all ( b"\n " ) ?;
235
-
236
- // SAFETY: Ensure the address and size are valid and accessible
237
- unsafe {
238
- let slice = std:: slice:: from_raw_parts ( address, size) ;
239
- file. write_all ( slice) ?;
240
- file. flush ( ) ?;
241
- }
242
- let persist_path = temp_path. with_extension ( "dmp" ) ;
243
- file. persist ( & persist_path)
244
- . map_err ( |e| new_error ! ( "Failed to persist file: {:?}" , e) ) ?;
245
-
246
- print ! ( "Memory dumped to file: {:?}" , persist_path) ;
247
- log:: error!( "Memory dumped to file: {:?}" , persist_path) ;
248
-
249
- Ok ( ( ) )
250
- }
190
+ #[ cfg( crashdump) ]
191
+ fn get_memory_regions ( & self ) -> & [ MemoryRegion ] ;
251
192
}
252
193
253
194
/// A virtual CPU that can be run until an exit occurs
@@ -271,11 +212,15 @@ impl VirtualCPU {
271
212
hv. handle_io ( port, data, rip, instruction_length, outb_handle_fn. clone ( ) ) ?
272
213
}
273
214
HyperlightExit :: Mmio ( addr) => {
215
+ #[ cfg( crashdump) ]
216
+ crashdump:: crashdump_to_tempfile ( hv) ?;
217
+
274
218
mem_access_fn
275
219
. clone ( )
276
220
. try_lock ( )
277
221
. map_err ( |e| new_error ! ( "Error locking at {}:{}: {}" , file!( ) , line!( ) , e) ) ?
278
222
. call ( ) ?;
223
+
279
224
log_then_return ! ( "MMIO access address {:#x}" , addr) ;
280
225
}
281
226
HyperlightExit :: AccessViolation ( addr, tried, region_permission) => {
0 commit comments