Skip to content

Commit 2242dbd

Browse files
authored
Merge pull request #41565 from compnerd/dump-arrays
swift-inspect: enable `dump-arrays` on Windows
2 parents f6ab0ae + 18ec9bf commit 2242dbd

File tree

6 files changed

+54
-12
lines changed

6 files changed

+54
-12
lines changed

tools/swift-inspect/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ The following inspection operations are available currently.
2222

2323
##### All Platforms
2424

25+
dump-arrays <name-or-pid>
26+
: Print information about array objects in the target
27+
2528
dump-cache-nodes <name-or-pid>
2629
: Print the metadata cache nodes.
2730

@@ -36,8 +39,5 @@ dump-raw-metadata <name-or-pid> [--backtrace] [--backtrace-long]
3639

3740
##### Darwin Only
3841

39-
dump-arrays <name-or-pid>
40-
: Print information about array objects in the target
41-
4242
dump-concurrency <name-or-pid>
43-
: Print information about tasks, actors, and threads under Concurrency.
43+
: Print information about tasks, actors, and threads under Concurrency.

tools/swift-inspect/Sources/swift-inspect/DarwinRemoteProcess.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,7 @@ internal final class DarwinRemoteProcess: RemoteProcess {
141141
let module = CSSymbolGetSymbolOwner(symbol)
142142
return (CSSymbolOwnerGetName(module), CSSymbolGetName(symbol))
143143
}
144-
}
145144

146-
extension DarwinRemoteProcess {
147145
internal func iterateHeap(_ body: (swift_addr_t, UInt64) -> Void) {
148146
withoutActuallyEscaping(body) {
149147
withUnsafePointer(to: $0) {
@@ -160,7 +158,9 @@ extension DarwinRemoteProcess {
160158
}
161159
}
162160
}
161+
}
163162

163+
extension DarwinRemoteProcess {
164164
internal var currentTasks: [(threadID: UInt64, currentTask: swift_addr_t)] {
165165
var threadList: UnsafeMutablePointer<thread_t>?
166166
var threadCount: mach_msg_type_number_t = 0

tools/swift-inspect/Sources/swift-inspect/Operations/DumpArray.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
1413
import ArgumentParser
1514
import SwiftRemoteMirror
1615

@@ -28,6 +27,7 @@ internal struct DumpArrays: ParsableCommand {
2827
let metadata: UInt =
2928
swift_reflection_metadataForObject(process.context, UInt(allocation))
3029
if metadata == 0 { return }
30+
3131
guard process.context.isContiguousArray(swift_reflection_ptr_t(metadata)) else {
3232
return
3333
}
@@ -44,5 +44,3 @@ internal struct DumpArrays: ParsableCommand {
4444
}
4545
}
4646
}
47-
48-
#endif

tools/swift-inspect/Sources/swift-inspect/RemoteProcess.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ internal protocol RemoteProcess: AnyObject {
4242
static var GetSymbolAddress: GetSymbolAddressFunction { get }
4343

4444
func symbolicate(_ address: swift_addr_t) -> (module: String?, symbol: String?)
45+
func iterateHeap(_ body: (swift_addr_t, UInt64) -> Void)
4546
}
4647

4748
extension RemoteProcess {

tools/swift-inspect/Sources/swift-inspect/WindowsRemoteProcess.swift

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,13 @@ internal final class WindowsRemoteProcess: RemoteProcess {
7979

8080
var information: WIN32_MEMORY_REGION_INFORMATION =
8181
WIN32_MEMORY_REGION_INFORMATION()
82-
_ = QueryVirtualMemoryInformation(process.process,
82+
if !QueryVirtualMemoryInformation(process.process,
8383
LPVOID(bitPattern: UInt(address)),
8484
MemoryRegionInfo, &information,
8585
SIZE_T(MemoryLayout.size(ofValue: information)),
86-
nil)
86+
nil) {
87+
return 0
88+
}
8789

8890
// FIXME(compnerd) mapping in the memory region from the remote process
8991
// would be ideal to avoid a round-trip for each byte. This seems to work
@@ -123,7 +125,7 @@ internal final class WindowsRemoteProcess: RemoteProcess {
123125
}
124126

125127
init?(processId: ProcessIdentifier) {
126-
// Setup process handle.
128+
// Get process handle.
127129
self.process =
128130
OpenProcess(DWORD(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ), false,
129131
processId)
@@ -223,6 +225,46 @@ internal final class WindowsRemoteProcess: RemoteProcess {
223225

224226
return (context.1, symbol)
225227
}
228+
229+
internal func iterateHeap(_ body: (swift_addr_t, UInt64) -> Void) {
230+
let dwProcessId: DWORD = GetProcessId(self.process)
231+
if dwProcessId == 0 {
232+
// FIXME(compnerd) log error
233+
return
234+
}
235+
236+
let hSnapshot: HANDLE =
237+
CreateToolhelp32Snapshot(DWORD(TH32CS_SNAPHEAPLIST), dwProcessId)
238+
if hSnapshot == INVALID_HANDLE_VALUE {
239+
// FIXME(compnerd) log error
240+
return
241+
}
242+
defer { CloseHandle(hSnapshot) }
243+
244+
var heap: HEAPLIST32 = HEAPLIST32()
245+
heap.dwSize = SIZE_T(MemoryLayout<HEAPLIST32>.size)
246+
if !Heap32ListFirst(hSnapshot, &heap) {
247+
// FIXME(compnerd) log error
248+
return
249+
}
250+
251+
repeat {
252+
var entry: HEAPENTRY32 = HEAPENTRY32()
253+
entry.dwSize = SIZE_T(MemoryLayout<HEAPENTRY32>.size)
254+
255+
if !Heap32First(&entry, dwProcessId, heap.th32HeapID) {
256+
// FIXME(compnerd) log error
257+
continue
258+
}
259+
260+
repeat {
261+
if entry.dwFlags & DWORD(LF32_FREE) == DWORD(LF32_FREE) { continue }
262+
body(swift_addr_t(entry.dwAddress), UInt64(entry.dwBlockSize))
263+
} while Heap32Next(&entry)
264+
265+
heap.dwSize = SIZE_T(MemoryLayout<HEAPLIST32>.size)
266+
} while Heap32ListNext(hSnapshot, &heap)
267+
}
226268
}
227269

228270
#endif

tools/swift-inspect/Sources/swift-inspect/main.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ internal struct SwiftInspect: ParsableCommand {
7777
DumpRawMetadata.self,
7878
DumpGenericMetadata.self,
7979
DumpCacheNodes.self,
80+
DumpArrays.self,
8081
]
8182
#endif
8283

0 commit comments

Comments
 (0)