@@ -69,16 +69,22 @@ internal final class AndroidRemoteProcess: LinuxRemoteProcess {
69
69
guard let ( mmapAddr, _) = symbolCache. address ( of: " mmap " ) else {
70
70
throw RemoteProcessError . missingSymbol ( " mmap " )
71
71
}
72
-
73
72
guard let ( munmapAddr, _) = symbolCache. address ( of: " munmap " ) else {
74
73
throw RemoteProcessError . missingSymbol ( " munmap " )
75
74
}
76
75
77
76
// We call malloc_iterate in the remote process to enumerate all items in
78
- // remote process' heap.
77
+ // remote process' heap. We use malloc_disable/malloc_enable to ensure no
78
+ // malloc/free requests can race with malloc_iterate.
79
+ guard let ( mallocDisableAddr, _) = symbolCache. address ( of: " malloc_disable " ) else {
80
+ throw RemoteProcessError . missingSymbol ( " malloc_disable " )
81
+ }
79
82
guard let ( mallocIterateAddr, _) = symbolCache. address ( of: " malloc_iterate " ) else {
80
83
throw RemoteProcessError . missingSymbol ( " malloc_iterate " )
81
84
}
85
+ guard let ( mallocEnableAddr, _) = symbolCache. address ( of: " malloc_enable " ) else {
86
+ throw RemoteProcessError . missingSymbol ( " malloc_enable " )
87
+ }
82
88
83
89
// Allocate a page-sized buffer in the remote process that malloc_iterate
84
90
// will populaate with metadata describing each heap entry it enumerates.
@@ -112,11 +118,18 @@ internal final class AndroidRemoteProcess: LinuxRemoteProcess {
112
118
_ = try ? self . ptrace. callRemoteFunction ( at: munmapAddr, with: munmapArgs)
113
119
}
114
120
115
- // copy the malloc_iterate callback implementation to the remote process
121
+ // Copy the malloc_iterate callback implementation to the remote process.
116
122
let codeStart = heap_iterate_callback_start ( ) !
117
123
try self . process. writeMem (
118
124
remoteAddr: remoteCodeAddr, localAddr: codeStart, len: UInt ( codeLen) )
119
125
126
+ // Disable malloc/free while enumerating the region to get a consistent
127
+ // snapshot of existing allocations.
128
+ _ = try self . ptrace. callRemoteFunction ( at: mallocDisableAddr)
129
+ defer {
130
+ _ = try ? self . ptrace. callRemoteFunction ( at: mallocEnableAddr)
131
+ }
132
+
120
133
var allocations : [ ( base: swift_addr_t , len: UInt64 ) ] = [ ]
121
134
let regionLen = endAddr - startAddr
122
135
let args = [ startAddr, regionLen, remoteCodeAddr, remoteDataAddr]
0 commit comments