Skip to content

Commit 94d824a

Browse files
Merge pull request swiftlang#39948 from aschwaighofer/swift-inspect-reflection-metadata
swift-inspect: load reflection metadata and use it to print whether array metadata is of a class element type
2 parents 0950626 + 3dfede7 commit 94d824a

File tree

5 files changed

+59
-2
lines changed

5 files changed

+59
-2
lines changed

tools/swift-inspect/Sources/swift-inspect/Inspector.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ class Inspector {
3434
mach_port_deallocate(mach_task_self_, task)
3535
}
3636

37+
func addReflectionInfoFromLoadedImages(context: SwiftReflectionContextRef) {
38+
var numSuccessfulImages = 0
39+
CSSymbolicatorForeachSymbolOwnerAtTime(symbolicator, kCSNow, { owner in
40+
let address = CSSymbolOwnerGetBaseAddress(owner);
41+
let name = CSSymbolOwnerGetName(owner)
42+
let _ = swift_reflection_addImage(context, address)
43+
})
44+
}
45+
3746
static func findTask(_ pid: pid_t, tryForkCorpse: Bool) -> task_t {
3847
var task = task_t()
3948
var kr = task_for_pid(mach_task_self_, pid, &task)

tools/swift-inspect/Sources/swift-inspect/Metadata.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ extension Allocation {
3535
let ptr = context.metadataPointer(allocation: allocation_t)
3636
if ptr != 0 {
3737
let name = context.name(metadata: ptr) ?? "<unknown>"
38-
return .init(ptr: ptr, name: name)
38+
let isClass = context.isAContiguousArrayOfClassElementType(metadata: ptr)
39+
return .init(ptr: ptr, name: name, isArrayOfClass: isClass)
3940
} else {
4041
return nil
4142
}
@@ -59,6 +60,7 @@ struct Metadata {
5960
let ptr: swift_reflection_ptr_t
6061
var allocation: Allocation? = nil
6162
let name: String
63+
let isArrayOfClass: Bool
6264

6365
var offset: Int? { allocation.map { Int(self.ptr - $0.ptr) } }
6466
}

tools/swift-inspect/Sources/swift-inspect/RemoteMirrorExtensions.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,29 @@ extension SwiftReflectionContextRef {
3131
return String(cString: cstr)
3232
}
3333

34+
func isAContiguousArrayOfClassElementType(metadata: swift_reflection_ptr_t) ->
35+
Bool {
36+
guard let name = name(metadata: metadata) else { return false }
37+
guard name.starts(with: "Swift._ContiguousArrayStorage") else {
38+
return false
39+
}
40+
let tr = swift_reflection_typeRefForMetadata(self, UInt(metadata));
41+
guard tr != 0 else {
42+
return false
43+
}
44+
let genericArgCnt = swift_reflection_genericArgumentCountOfTypeRef(tr);
45+
guard genericArgCnt == 1 else {
46+
return false
47+
}
48+
49+
let argTr = swift_reflection_genericArgumentOfTypeRef(tr, 0)
50+
guard argTr != 0 else {
51+
return false
52+
}
53+
let typeInfo = swift_reflection_infoForTypeRef(self, argTr)
54+
return typeInfo.Kind == SWIFT_STRONG_REFERENCE
55+
}
56+
3457
func name(proto: swift_reflection_ptr_t) -> String? {
3558
guard let cstr = swift_reflection_copyDemangledNameForProtocolDescriptor(
3659
self, proto) else { return nil }

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func dumpGenericMetadata(
5656
let metadatas = allocations.findGenericMetadata(in: context)
5757
let backtraces = backtraceStyle != nil ? context.allocationBacktraces : [:]
5858

59-
print("Address","Allocation","Size","Offset","Name", separator: "\t")
59+
print("Address","Allocation","Size","Offset","isArrayOfClass", "Name", separator: "\t")
6060
for metadata in metadatas {
6161
print("\(hex: metadata.ptr)", terminator: "\t")
6262

@@ -66,6 +66,7 @@ func dumpGenericMetadata(
6666
} else {
6767
print("???\t???\t???", terminator: "\t")
6868
}
69+
print(metadata.isArrayOfClass, terminator: "\t")
6970
print(metadata.name)
7071
if let allocation = metadata.allocation {
7172
printBacktrace(style: backtraceStyle, for: allocation.ptr, in: backtraces, inspector: inspector)
@@ -126,6 +127,8 @@ func makeReflectionContext(
126127
argFail("Failed to create reflection context")
127128
}
128129

130+
inspector.addReflectionInfoFromLoadedImages(context: reflectionContext)
131+
129132
return (inspector, reflectionContext)
130133
}
131134

tools/swift-inspect/Sources/swift-inspect/symbolication.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ enum Sym {
6969
symbol(symbolicationHandle, "task_peek_string")
7070
static let task_stop_peeking: @convention(c) (task_t) -> kern_return_t =
7171
symbol(symbolicationHandle, "task_stop_peeking")
72+
73+
static let CSSymbolicatorForeachSymbolOwnerAtTime:
74+
@convention(c) (CSSymbolicatorRef, CSMachineTime, @convention(block) (CSSymbolOwnerRef) -> Void) -> UInt =
75+
symbol(coreSymbolicationHandle, "CSSymbolicatorForeachSymbolOwnerAtTime")
76+
77+
static let CSSymbolOwnerGetBaseAddress: @convention(c) (CSSymbolOwnerRef) -> mach_vm_address_t =
78+
symbol(symbolicationHandle, "CSSymbolOwnerGetBaseAddress")
7279
}
7380

7481
typealias CSMachineTime = UInt64
@@ -145,6 +152,19 @@ func CSSymbolicatorGetSymbolWithAddressAtTime(
145152
Sym.CSSymbolicatorGetSymbolWithAddressAtTime(symbolicator, address, time)
146153
}
147154

155+
func CSSymbolicatorForeachSymbolOwnerAtTime(
156+
_ symbolicator: CSSymbolicatorRef,
157+
_ time: CSMachineTime,
158+
_ symbolIterator: (CSSymbolOwnerRef) -> Void
159+
) -> UInt {
160+
return Sym.CSSymbolicatorForeachSymbolOwnerAtTime(symbolicator, time,
161+
symbolIterator)
162+
}
163+
164+
func CSSymbolOwnerGetBaseAddress(_ symbolOwner: CSSymbolOwnerRef) -> mach_vm_address_t {
165+
return Sym.CSSymbolOwnerGetBaseAddress(symbolOwner)
166+
}
167+
148168
func task_start_peeking(_ task: task_t) -> Bool {
149169
let result = Sym.task_start_peeking(task)
150170
if result == KERN_SUCCESS {

0 commit comments

Comments
 (0)