@@ -187,13 +187,20 @@ pub fn munmap(start: Address, size: usize) -> Result<()> {
187187
188188/// Properly handle errors from a mmap Result, including invoking the binding code in the case of
189189/// an OOM error.
190- pub fn handle_mmap_error < VM : VMBinding > ( error : Error , tls : VMThread ) -> ! {
190+ pub fn handle_mmap_error < VM : VMBinding > (
191+ error : Error ,
192+ tls : VMThread ,
193+ addr : Address ,
194+ bytes : usize ,
195+ ) -> ! {
191196 use std:: io:: ErrorKind ;
192197
198+ eprintln ! ( "Failed to mmap {}, size {}" , addr, bytes) ;
199+ eprintln ! ( "{}" , get_process_memory_maps( ) ) ;
200+
193201 match error. kind ( ) {
194202 // From Rust nightly 2021-05-12, we started to see Rust added this ErrorKind.
195203 ErrorKind :: OutOfMemory => {
196- eprintln ! ( "{}" , get_process_memory_maps( ) ) ;
197204 // Signal `MmapOutOfMemory`. Expect the VM to abort immediately.
198205 trace ! ( "Signal MmapOutOfMemory!" ) ;
199206 VM :: VMCollection :: out_of_memory ( tls, AllocationError :: MmapOutOfMemory ) ;
@@ -206,7 +213,6 @@ pub fn handle_mmap_error<VM: VMBinding>(error: Error, tls: VMThread) -> ! {
206213 if let Some ( os_errno) = error. raw_os_error ( ) {
207214 // If it is OOM, we invoke out_of_memory() through the VM interface.
208215 if os_errno == libc:: ENOMEM {
209- eprintln ! ( "{}" , get_process_memory_maps( ) ) ;
210216 // Signal `MmapOutOfMemory`. Expect the VM to abort immediately.
211217 trace ! ( "Signal MmapOutOfMemory!" ) ;
212218 VM :: VMCollection :: out_of_memory ( tls, AllocationError :: MmapOutOfMemory ) ;
@@ -215,12 +221,10 @@ pub fn handle_mmap_error<VM: VMBinding>(error: Error, tls: VMThread) -> ! {
215221 }
216222 }
217223 ErrorKind :: AlreadyExists => {
218- eprintln ! ( "{}" , get_process_memory_maps( ) ) ;
219224 panic ! ( "Failed to mmap, the address is already mapped. Should MMTk quarantine the address range first?" ) ;
220225 }
221226 _ => { }
222227 }
223- eprintln ! ( "{}" , get_process_memory_maps( ) ) ;
224228 panic ! ( "Unexpected mmap failure: {:?}" , error)
225229}
226230
@@ -301,7 +305,34 @@ pub fn get_process_memory_maps() -> String {
301305
302306/// Get the memory maps for the process. The returned string is a multi-line string.
303307/// This is only meant to be used for debugging. For example, log process memory maps after detecting a clash.
304- #[ cfg( not( any( target_os = "linux" , target_os = "android" ) ) ) ]
308+ #[ cfg( target_os = "macos" ) ]
309+ pub fn get_process_memory_maps ( ) -> String {
310+ // Get the current process ID (replace this with a specific PID if needed)
311+ let pid = std:: process:: id ( ) ;
312+
313+ // Execute the vmmap command
314+ let output = std:: process:: Command :: new ( "vmmap" )
315+ . arg ( pid. to_string ( ) ) // Pass the PID as an argument
316+ . output ( ) // Capture the output
317+ . expect ( "Failed to execute vmmap command" ) ;
318+
319+ // Check if the command was successful
320+ if output. status . success ( ) {
321+ // Convert the command output to a string
322+ let output_str =
323+ std:: str:: from_utf8 ( & output. stdout ) . expect ( "Failed to convert output to string" ) ;
324+ output_str. to_string ( )
325+ } else {
326+ // Handle the error case
327+ let error_message =
328+ std:: str:: from_utf8 ( & output. stderr ) . expect ( "Failed to convert error message to string" ) ;
329+ panic ! ( "Failed to get process memory map: {}" , error_message)
330+ }
331+ }
332+
333+ /// Get the memory maps for the process. The returned string is a multi-line string.
334+ /// This is only meant to be used for debugging. For example, log process memory maps after detecting a clash.
335+ #[ cfg( not( any( target_os = "linux" , target_os = "android" , target_os = "macos" ) ) ) ]
305336pub fn get_process_memory_maps ( ) -> String {
306337 "(process map unavailable)" . to_string ( )
307338}
0 commit comments