13
13
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
14
14
15
15
import SwiftRemoteMirror
16
- @ _implementationOnly import SymbolicationShims
16
+ import SymbolicationShims
17
17
18
18
internal final class DarwinRemoteProcess : RemoteProcess {
19
19
public typealias ProcessIdentifier = pid_t
@@ -23,8 +23,10 @@ internal final class DarwinRemoteProcess: RemoteProcess {
23
23
24
24
public var process : ProcessHandle { task }
25
25
public private( set) var context : SwiftReflectionContextRef !
26
+ private var symbolicator : CSSymbolicatorRef
26
27
27
28
private var swiftCore : CSTypeRef
29
+ private let swiftConcurrency : CSTypeRef
28
30
29
31
static var QueryDataLayout : QueryDataLayoutFunction {
30
32
return { ( context, type, _, output) in
@@ -38,7 +40,7 @@ internal final class DarwinRemoteProcess: RemoteProcess {
38
40
39
41
case DLQ_GetPtrAuthMask:
40
42
let mask = GetPtrauthMask ( )
41
- output. storeBytes ( of: mask, toByteOffset: 0 , as: UInt . size )
43
+ output. storeBytes ( of: mask, toByteOffset: 0 , as: UInt . self )
42
44
return 1
43
45
44
46
case DLQ_GetObjCReservedLowBits:
@@ -65,10 +67,25 @@ internal final class DarwinRemoteProcess: RemoteProcess {
65
67
}
66
68
}
67
69
70
+ func read( address: swift_addr_t , size: Int ) -> UnsafeRawPointer ? {
71
+ return task_peek ( task, address, mach_vm_size_t ( size) )
72
+ }
73
+
74
+ func getAddr( symbolName: String ) -> swift_addr_t {
75
+ // FIXME: use `__USER_LABEL_PREFIX__` instead of the hardcoded `_`.
76
+ let fullName = " _ \( symbolName) "
77
+ let symbol = CSSymbolOwnerGetSymbolWithMangledName ( swiftCore, fullName)
78
+ if CSIsNull ( symbol) {
79
+ symbol = CSSymbolOwnerGetSymbolWithMangledName ( swiftConcurrency, fullName)
80
+ }
81
+ let range = CSSymbolGetRange ( symbol)
82
+ return swift_addr_t ( range. location)
83
+ }
84
+
68
85
static var ReadBytes : ReadBytesFunction {
69
86
return { ( context, address, size, _) in
70
87
let process : DarwinRemoteProcess = DarwinRemoteProcess . fromOpaque ( context!)
71
- return task_peek ( process. task , address, size)
88
+ return process. read ( address : address, size: Int ( size ) )
72
89
}
73
90
}
74
91
@@ -90,11 +107,7 @@ internal final class DarwinRemoteProcess: RemoteProcess {
90
107
let buffer = UnsafeBufferPointer ( start: $0, count: Int ( length) )
91
108
return String ( decoding: buffer, as: UTF8 . self)
92
109
}
93
-
94
- let symbol =
95
- CSSymbolOwnerGetSymbolWithMangledName ( process. swiftCore, " _ \( name) " )
96
- // FIXME: use `__USER_LABEL_PREFIX__` instead of the hardcoded `_`.
97
- return swift_addr_t ( CSSymbolGetRange ( symbol) . location)
110
+ return process. getAddr ( symbolName: name)
98
111
}
99
112
}
100
113
@@ -107,6 +120,14 @@ internal final class DarwinRemoteProcess: RemoteProcess {
107
120
}
108
121
self . task = task
109
122
123
+ self . symbolicator = CSSymbolicatorCreateWithTask ( self . task)
124
+ self . swiftCore =
125
+ CSSymbolicatorGetSymbolOwnerWithNameAtTime ( self . symbolicator,
126
+ " libswiftCore.dylib " , kCSNow)
127
+ self . swiftConcurrency = CSSymbolicatorGetSymbolOwnerWithNameAtTime (
128
+ symbolicator, " libswift_Concurrency.dylib " , kCSNow)
129
+ _ = task_start_peeking ( self . task)
130
+
110
131
guard let context =
111
132
swift_reflection_createReflectionContextWithDataLayout ( self . toOpaqueRef ( ) ,
112
133
Self . QueryDataLayout,
@@ -116,12 +137,7 @@ internal final class DarwinRemoteProcess: RemoteProcess {
116
137
Self . GetSymbolAddress) else {
117
138
return nil
118
139
}
119
-
120
- self . symbolicator = CSSymbolicatorCreateWithTask ( self . task)
121
- self . swiftCore =
122
- CSSymbolicatorGetSymbolOwnerWithNameAtTime ( self . symbolicator,
123
- " libswiftCore.dylib " , kCSNow)
124
- _ = task_start_peeking ( self . task)
140
+ self . context = context
125
141
126
142
_ = CSSymbolicatorForeachSymbolOwnerAtTime ( self . symbolicator, kCSNow, { owner in
127
143
let address = CSSymbolOwnerGetBaseAddress ( owner)
@@ -136,7 +152,7 @@ internal final class DarwinRemoteProcess: RemoteProcess {
136
152
137
153
func symbolicate( _ address: swift_addr_t ) -> ( module: String ? , symbol: String ? ) {
138
154
let symbol =
139
- CSSymbolicatorGetSymbolWithAddressAtTime ( sself . symbolicator, address, kCSNow)
155
+ CSSymbolicatorGetSymbolWithAddressAtTime ( self . symbolicator, address, kCSNow)
140
156
141
157
let module = CSSymbolGetSymbolOwner ( symbol)
142
158
return ( CSSymbolOwnerGetName ( module) , CSSymbolGetName ( symbol) )
@@ -153,8 +169,9 @@ extension DarwinRemoteProcess {
153
169
{ ( task, context, type, ranges, count) in
154
170
let callback : ( swift_addr_t , UInt64 ) -> Void =
155
171
context!. assumingMemoryBound ( to: ( ( swift_addr_t, UInt64) - > Void) . self) . pointee
156
- ranges. forEach {
157
- callback ( swift_addr_t ( $0. address) , UInt64 ( $0. size) )
172
+ for i in 0 ..< Int ( count) {
173
+ let range = ranges [ i]
174
+ callback ( swift_addr_t ( range. address) , UInt64 ( range. size) )
158
175
}
159
176
} )
160
177
}
@@ -196,24 +213,24 @@ extension DarwinRemoteProcess {
196
213
let result =
197
214
thread_info ( threadList![ i] , thread_flavor_t ( THREAD_IDENTIFIER_INFO) ,
198
215
$0, & infoCount)
199
- guard result == ERROR_SUCCESS else {
216
+ guard result == KERN_SUCCESS else {
200
217
print ( " unable to get info for thread \( i) : \( String ( cString: mach_error_string ( result) ) ) (0x \( String ( result, radix: 16 ) ) ) " )
201
218
return
202
219
}
220
+ }
221
+ }
203
222
204
- let tlsStart = info. thread_handle
205
- if tlsStart == 0 { return }
223
+ let tlsStart = info. thread_handle
224
+ if tlsStart == 0 { continue }
206
225
207
- let SWIFT_CONCURRENCY_TASK_KEY = 103
208
- let currentTaskPointer = tlsStart + UInt64( SWIFT_CONCURRENCY_TASK_KEY * MemoryLayout< UnsafeRawPointer> . size)
209
- if let pointer = ReadBytes ( currentTaskPointer, size: MemoryLayout< UnsafeRawPointer> . size) {
210
- let currentTask = pointer. load ( as: UInt . self)
211
- results. append ( ( threadID: info. thread_id, currentTask: swift_addr_t ( currentTask) ) )
212
- }
213
- }
226
+ let SWIFT_CONCURRENCY_TASK_KEY = 103
227
+ let currentTaskPointer = tlsStart + UInt64( SWIFT_CONCURRENCY_TASK_KEY * MemoryLayout< UnsafeRawPointer> . size)
228
+ if let pointer = read ( address: currentTaskPointer, size: MemoryLayout< UnsafeRawPointer> . size) {
229
+ let currentTask = pointer. load ( as: UInt . self)
230
+ results. append ( ( threadID: info. thread_id, currentTask: swift_addr_t ( currentTask) ) )
214
231
}
215
232
}
216
- return result
233
+ return results
217
234
}
218
235
}
219
236
0 commit comments