Skip to content

Commit 25da1a9

Browse files
committed
[swift-inspect] use malloc_disable/malloc_enable when iterating the heap
on Android
1 parent 714ce52 commit 25da1a9

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

tools/swift-inspect/Sources/swift-inspect/AndroidRemoteProcess.swift

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,22 @@ internal final class AndroidRemoteProcess: LinuxRemoteProcess {
6969
guard let (mmapAddr, _) = symbolCache.address(of: "mmap") else {
7070
throw RemoteProcessError.missingSymbol("mmap")
7171
}
72-
7372
guard let (munmapAddr, _) = symbolCache.address(of: "munmap") else {
7473
throw RemoteProcessError.missingSymbol("munmap")
7574
}
7675

7776
// 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+
}
7982
guard let (mallocIterateAddr, _) = symbolCache.address(of: "malloc_iterate") else {
8083
throw RemoteProcessError.missingSymbol("malloc_iterate")
8184
}
85+
guard let (mallocEnableAddr, _) = symbolCache.address(of: "malloc_enable") else {
86+
throw RemoteProcessError.missingSymbol("malloc_enable")
87+
}
8288

8389
// Allocate a page-sized buffer in the remote process that malloc_iterate
8490
// will populaate with metadata describing each heap entry it enumerates.
@@ -112,11 +118,18 @@ internal final class AndroidRemoteProcess: LinuxRemoteProcess {
112118
_ = try? self.ptrace.callRemoteFunction(at: munmapAddr, with: munmapArgs)
113119
}
114120

115-
// copy the malloc_iterate callback implementation to the remote process
121+
// Copy the malloc_iterate callback implementation to the remote process.
116122
let codeStart = heap_iterate_callback_start()!
117123
try self.process.writeMem(
118124
remoteAddr: remoteCodeAddr, localAddr: codeStart, len: UInt(codeLen))
119125

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+
120133
var allocations: [(base: swift_addr_t, len: UInt64)] = []
121134
let regionLen = endAddr - startAddr
122135
let args = [startAddr, regionLen, remoteCodeAddr, remoteDataAddr]

0 commit comments

Comments
 (0)