@@ -187,13 +187,20 @@ pub fn munmap(start: Address, size: usize) -> Result<()> {
187
187
188
188
/// Properly handle errors from a mmap Result, including invoking the binding code in the case of
189
189
/// 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
+ ) -> ! {
191
196
use std:: io:: ErrorKind ;
192
197
198
+ eprintln ! ( "Failed to mmap {}, size {}" , addr, bytes) ;
199
+ eprintln ! ( "{}" , get_process_memory_maps( ) ) ;
200
+
193
201
match error. kind ( ) {
194
202
// From Rust nightly 2021-05-12, we started to see Rust added this ErrorKind.
195
203
ErrorKind :: OutOfMemory => {
196
- eprintln ! ( "{}" , get_process_memory_maps( ) ) ;
197
204
// Signal `MmapOutOfMemory`. Expect the VM to abort immediately.
198
205
trace ! ( "Signal MmapOutOfMemory!" ) ;
199
206
VM :: VMCollection :: out_of_memory ( tls, AllocationError :: MmapOutOfMemory ) ;
@@ -206,7 +213,6 @@ pub fn handle_mmap_error<VM: VMBinding>(error: Error, tls: VMThread) -> ! {
206
213
if let Some ( os_errno) = error. raw_os_error ( ) {
207
214
// If it is OOM, we invoke out_of_memory() through the VM interface.
208
215
if os_errno == libc:: ENOMEM {
209
- eprintln ! ( "{}" , get_process_memory_maps( ) ) ;
210
216
// Signal `MmapOutOfMemory`. Expect the VM to abort immediately.
211
217
trace ! ( "Signal MmapOutOfMemory!" ) ;
212
218
VM :: VMCollection :: out_of_memory ( tls, AllocationError :: MmapOutOfMemory ) ;
@@ -215,12 +221,10 @@ pub fn handle_mmap_error<VM: VMBinding>(error: Error, tls: VMThread) -> ! {
215
221
}
216
222
}
217
223
ErrorKind :: AlreadyExists => {
218
- eprintln ! ( "{}" , get_process_memory_maps( ) ) ;
219
224
panic ! ( "Failed to mmap, the address is already mapped. Should MMTk quarantine the address range first?" ) ;
220
225
}
221
226
_ => { }
222
227
}
223
- eprintln ! ( "{}" , get_process_memory_maps( ) ) ;
224
228
panic ! ( "Unexpected mmap failure: {:?}" , error)
225
229
}
226
230
@@ -301,7 +305,34 @@ pub fn get_process_memory_maps() -> String {
301
305
302
306
/// Get the memory maps for the process. The returned string is a multi-line string.
303
307
/// 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" ) ) ) ]
305
336
pub fn get_process_memory_maps ( ) -> String {
306
337
"(process map unavailable)" . to_string ( )
307
338
}
0 commit comments