@@ -1127,51 +1127,112 @@ mod tests {
11271127 assert_eq ! ( data, ret_vec) ;
11281128 }
11291129
1130- /// A test to ensure that, if a `SharedMem` instance is cloned
1131- /// and _all_ clones are dropped, the memory region will no longer
1132- /// be valid.
1133- ///
1134- /// This test is ignored because it is incompatible with other tests as
1135- /// they may be allocating memory at the same time.
1136- ///
1137- /// Marking this test as ignored means that running `cargo test` will not
1138- /// run it. This feature will allow a developer who runs that command
1139- /// from their workstation to be successful without needing to know about
1140- /// test interdependencies. This test will, however, be run explicitly as a
1141- /// part of the CI pipeline.
1130+ /// Makes sure drop actually frees the underlying memory
11421131 #[ test]
1143- #[ ignore]
1144- #[ cfg( target_os = "linux" ) ]
11451132 fn test_drop ( ) {
1146- use proc_maps:: maps_contain_addr;
1147-
1148- let pid = std:: process:: id ( ) ;
1149-
11501133 let eshm = ExclusiveSharedMemory :: new ( PAGE_SIZE_USIZE ) . unwrap ( ) ;
11511134 let ( hshm1, gshm) = eshm. build ( ) ;
11521135 let hshm2 = hshm1. clone ( ) ;
1153- let addr = hshm1. raw_ptr ( ) as usize ;
1154-
1155- // ensure the address is in the process's virtual memory
1156- let maps_before_drop = proc_maps:: get_process_maps ( pid. try_into ( ) . unwrap ( ) ) . unwrap ( ) ;
1157- assert ! (
1158- maps_contain_addr( addr, & maps_before_drop) ,
1159- "shared memory address {:#x} was not found in process map, but should be" ,
1160- addr,
1161- ) ;
1162- // drop both shared memory instances, which should result
1136+ let addr = hshm1. raw_ptr ( ) ;
1137+ let _size = hshm1. raw_mem_size ( ) ;
1138+
1139+ // Verify memory is initially accessible
1140+ #[ cfg( target_os = "linux" ) ]
1141+ {
1142+ let result =
1143+ unsafe { libc:: madvise ( addr as * mut libc:: c_void , _size, libc:: MADV_NORMAL ) } ;
1144+ assert_eq ! (
1145+ result,
1146+ 0 ,
1147+ "Memory should be accessible before drop - madvise failed with errno: {}" ,
1148+ std:: io:: Error :: last_os_error( ) . raw_os_error( ) . unwrap( )
1149+ ) ;
1150+ }
1151+
1152+ #[ cfg( target_os = "windows" ) ]
1153+ {
1154+ use core:: ffi:: c_void;
1155+
1156+ use windows:: Win32 :: System :: Memory :: {
1157+ MEM_FREE , MEMORY_BASIC_INFORMATION , VirtualQuery ,
1158+ } ;
1159+
1160+ let mut mbi = MEMORY_BASIC_INFORMATION :: default ( ) ;
1161+ let result = unsafe {
1162+ VirtualQuery (
1163+ Some ( addr as * const c_void ) ,
1164+ & mut mbi,
1165+ std:: mem:: size_of :: < MEMORY_BASIC_INFORMATION > ( ) ,
1166+ )
1167+ } ;
1168+ assert_ne ! (
1169+ result, 0 ,
1170+ "VirtualQuery should succeed on mapped memory at address {:#x}" ,
1171+ addr as usize
1172+ ) ;
1173+ assert_ne ! (
1174+ mbi. State , MEM_FREE ,
1175+ "Memory should not be in MEM_FREE state before drop at address {:#x}" ,
1176+ addr as usize
1177+ ) ;
1178+ }
1179+
1180+ // Drop both shared memory instances, which should result
11631181 // in freeing the memory region
11641182 drop ( hshm1) ;
11651183 drop ( hshm2) ;
11661184 drop ( gshm) ;
11671185
1168- let maps_after_drop = proc_maps:: get_process_maps ( pid. try_into ( ) . unwrap ( ) ) . unwrap ( ) ;
1169- // now, ensure the address is not in the process's virtual memory
1170- assert ! (
1171- !maps_contain_addr( addr, & maps_after_drop) ,
1172- "shared memory address {:#x} was found in the process map, but shouldn't be" ,
1173- addr
1174- ) ;
1186+ // Verify memory is no longer accessible
1187+ #[ cfg( target_os = "linux" ) ]
1188+ {
1189+ // Try madvise on the unmapped memory - should fail with ENOMEM
1190+ let result =
1191+ unsafe { libc:: madvise ( addr as * mut libc:: c_void , _size, libc:: MADV_NORMAL ) } ;
1192+ assert_eq ! (
1193+ result, -1 ,
1194+ "madvise should return -1 on unmapped memory at address {:#x}" ,
1195+ addr as usize
1196+ ) ;
1197+
1198+ let errno = std:: io:: Error :: last_os_error ( ) . raw_os_error ( ) . unwrap_or ( -1 ) ;
1199+ assert_eq ! (
1200+ errno,
1201+ libc:: ENOMEM ,
1202+ "Expected ENOMEM for unmapped memory, but got errno: {} at address {:#x}" ,
1203+ errno,
1204+ addr as usize
1205+ ) ;
1206+ }
1207+
1208+ #[ cfg( target_os = "windows" ) ]
1209+ {
1210+ use core:: ffi:: c_void;
1211+
1212+ use windows:: Win32 :: System :: Memory :: {
1213+ MEM_FREE , MEMORY_BASIC_INFORMATION , VirtualQuery ,
1214+ } ;
1215+
1216+ // Try VirtualQuery on the unmapped memory - should show MEM_FREE state
1217+ let mut mbi_after = MEMORY_BASIC_INFORMATION :: default ( ) ;
1218+ let result = unsafe {
1219+ VirtualQuery (
1220+ Some ( addr as * const c_void ) ,
1221+ & mut mbi_after,
1222+ std:: mem:: size_of :: < MEMORY_BASIC_INFORMATION > ( ) ,
1223+ )
1224+ } ;
1225+ assert_ne ! (
1226+ result, 0 ,
1227+ "VirtualQuery should succeed even on unmapped memory at address {:#x}" ,
1228+ addr as usize
1229+ ) ;
1230+ assert_eq ! (
1231+ mbi_after. State , MEM_FREE ,
1232+ "Memory should be in MEM_FREE state after drop at address {:#x}" ,
1233+ addr as usize
1234+ ) ;
1235+ }
11751236 }
11761237
11771238 #[ cfg( target_os = "linux" ) ]
0 commit comments