@@ -19,13 +19,25 @@ internal final class DarwinRemoteProcess: RemoteProcess {
19
19
public typealias ProcessIdentifier = pid_t
20
20
public typealias ProcessHandle = task_t
21
21
22
- private var task : task_t
22
+ private var task = Cleanup< task_t> {
23
+ // task_stop_peeking does nothing if we didn't task_start_peeking first, so
24
+ // we can call it unconditionally.
25
+ task_stop_peeking ( $0)
26
+ mach_port_deallocate ( mach_task_self_, $0)
27
+ }
28
+
23
29
internal var processIdentifier : ProcessIdentifier
24
30
internal lazy var processName = getProcessName ( processId: processIdentifier) ?? " <unknown process> "
25
31
26
- public var process : ProcessHandle { task }
27
- public private( set) var context : SwiftReflectionContextRef !
28
- private var symbolicator : CSSymbolicatorRef
32
+ public var process : ProcessHandle { task. value }
33
+ private var _context = Cleanup< SwiftReflectionContextRef> {
34
+ swift_reflection_destroyReflectionContext ( $0)
35
+ }
36
+ public var context : SwiftReflectionContextRef ! { _context. value }
37
+
38
+ private var symbolicator = Cleanup< CSSymbolicatorRef> {
39
+ CSRelease ( $0)
40
+ }
29
41
30
42
private var swiftCore : CSTypeRef
31
43
private let swiftConcurrency : CSTypeRef
@@ -72,7 +84,7 @@ internal final class DarwinRemoteProcess: RemoteProcess {
72
84
}
73
85
74
86
func read( address: swift_addr_t , size: Int ) -> UnsafeRawPointer ? {
75
- return task_peek ( task, address, mach_vm_size_t ( size) )
87
+ return task_peek ( task. value , address, mach_vm_size_t ( size) )
76
88
}
77
89
78
90
func getAddr( symbolName: String ) -> swift_addr_t {
@@ -98,7 +110,7 @@ internal final class DarwinRemoteProcess: RemoteProcess {
98
110
static var GetStringLength : GetStringLengthFunction {
99
111
return { ( context, address) in
100
112
let process : DarwinRemoteProcess = DarwinRemoteProcess . fromOpaque ( context!)
101
- if let str = task_peek_string ( process. task, address) {
113
+ if let str = task_peek_string ( process. task. value , address) {
102
114
return UInt64 ( strlen ( str) )
103
115
}
104
116
return 0
@@ -119,18 +131,19 @@ internal final class DarwinRemoteProcess: RemoteProcess {
119
131
120
132
init ? ( processId: ProcessIdentifier , forkCorpse: Bool ) {
121
133
processIdentifier = processId
122
- var task : task_t = task_t ( )
123
- let taskResult = task_for_pid ( mach_task_self_, processId, & task )
134
+ var processTask : task_t = task_t ( )
135
+ let taskResult = task_for_pid ( mach_task_self_, processId, & processTask )
124
136
guard taskResult == KERN_SUCCESS else {
125
137
print ( " unable to get task for pid \( processId) : \( String ( cString: mach_error_string ( taskResult) ) ) \( hex: taskResult) " ,
126
138
to: & Std. err)
127
139
return nil
128
140
}
141
+ self . task. value = processTask
129
142
130
143
// Consult with VMUProcInfo to determine if we should force forkCorpse.
131
144
let forceForkCorpse : Bool
132
145
if let procInfoClass = getVMUProcInfoClass ( ) {
133
- let procInfo = procInfoClass. init ( task: task)
146
+ let procInfo = procInfoClass. init ( task: self . task. value )
134
147
forceForkCorpse = procInfo. shouldAnalyzeWithCorpse
135
148
} else {
136
149
// Default to not forcing forkCorpse.
@@ -141,11 +154,9 @@ internal final class DarwinRemoteProcess: RemoteProcess {
141
154
var corpse = task_t ( )
142
155
let maxRetry = 6
143
156
for retry in 0 ..< maxRetry {
144
- let corpseResult = task_generate_corpse ( task, & corpse)
157
+ let corpseResult = task_generate_corpse ( task. value , & corpse)
145
158
if corpseResult == KERN_SUCCESS {
146
- task_stop_peeking ( task)
147
- mach_port_deallocate ( mach_task_self_, task)
148
- task = corpse
159
+ task. value = corpse
149
160
break
150
161
}
151
162
if corpseResult != KERN_RESOURCE_SHORTAGE || retry == maxRetry {
@@ -157,20 +168,19 @@ internal final class DarwinRemoteProcess: RemoteProcess {
157
168
}
158
169
}
159
170
160
- self . task = task
171
+ self . symbolicator. value = CSSymbolicatorCreateWithTask ( self . task. value)
172
+
173
+ self . swiftCore = CSSymbolicatorGetSymbolOwnerWithNameAtTime (
174
+ self . symbolicator. value, " libswiftCore.dylib " , kCSNow)
175
+ self . swiftConcurrency = CSSymbolicatorGetSymbolOwnerWithNameAtTime (
176
+ self . symbolicator. value, " libswift_Concurrency.dylib " , kCSNow)
161
177
162
- self . symbolicator = CSSymbolicatorCreateWithTask ( self . task)
163
- self . swiftCore =
164
- CSSymbolicatorGetSymbolOwnerWithNameAtTime ( self . symbolicator,
165
- " libswiftCore.dylib " , kCSNow)
166
178
if CSIsNull ( self . swiftCore) {
167
179
print ( " pid \( processId) does not have libswiftCore.dylib loaded " )
168
180
return nil
169
181
}
170
182
171
- self . swiftConcurrency = CSSymbolicatorGetSymbolOwnerWithNameAtTime (
172
- symbolicator, " libswift_Concurrency.dylib " , kCSNow)
173
- _ = task_start_peeking ( self . task)
183
+ _ = task_start_peeking ( self . task. value)
174
184
175
185
guard let context =
176
186
swift_reflection_createReflectionContextWithDataLayout ( self . toOpaqueRef ( ) ,
@@ -181,23 +191,17 @@ internal final class DarwinRemoteProcess: RemoteProcess {
181
191
Self . GetSymbolAddress) else {
182
192
return nil
183
193
}
184
- self . context = context
194
+ self . _context . value = context
185
195
186
- _ = CSSymbolicatorForeachSymbolOwnerAtTime ( self . symbolicator, kCSNow, { owner in
196
+ _ = CSSymbolicatorForeachSymbolOwnerAtTime ( self . symbolicator. value , kCSNow, { owner in
187
197
let address = CSSymbolOwnerGetBaseAddress ( owner)
188
198
_ = swift_reflection_addImage ( self . context, address)
189
199
} )
190
200
}
191
201
192
- deinit {
193
- task_stop_peeking ( self . task)
194
- CSRelease ( self . symbolicator)
195
- mach_port_deallocate ( mach_task_self_, self . task)
196
- }
197
-
198
202
func symbolicate( _ address: swift_addr_t ) -> ( module: String ? , symbol: String ? ) {
199
203
let symbol =
200
- CSSymbolicatorGetSymbolWithAddressAtTime ( self . symbolicator, address, kCSNow)
204
+ CSSymbolicatorGetSymbolWithAddressAtTime ( self . symbolicator. value , address, kCSNow)
201
205
202
206
let module = CSSymbolGetSymbolOwner ( symbol)
203
207
return ( CSSymbolOwnerGetName ( module) , CSSymbolGetName ( symbol) )
@@ -206,7 +210,7 @@ internal final class DarwinRemoteProcess: RemoteProcess {
206
210
internal func iterateHeap( _ body: ( swift_addr_t , UInt64 ) -> Void ) {
207
211
withoutActuallyEscaping ( body) {
208
212
withUnsafePointer ( to: $0) {
209
- task_enumerate_malloc_blocks ( self . task,
213
+ task_enumerate_malloc_blocks ( self . task. value ,
210
214
UnsafeMutableRawPointer ( mutating: $0) ,
211
215
CUnsignedInt ( MALLOC_PTR_IN_USE_RANGE_TYPE) ,
212
216
{ ( task, context, type, ranges, count) in
@@ -264,14 +268,14 @@ extension DarwinRemoteProcess {
264
268
}
265
269
266
270
private func getThreadInfos( ) -> [ ThreadInfo ] {
267
- guard let threads = PortList ( task: self . task) else {
271
+ guard let threads = PortList ( task: self . task. value ) else {
268
272
return [ ]
269
273
}
270
- return threads. compactMap {
271
- guard let info = getThreadInfo ( thread: $0 ) else {
274
+ return threads. compactMap { t -> ThreadInfo ? in
275
+ guard let info = getThreadInfo ( thread: t ) else {
272
276
return nil
273
277
}
274
- guard let kernelObj = getKernelObject ( task: mach_task_self_, port: $0 ) else {
278
+ guard let kernelObj = getKernelObject ( task: mach_task_self_, port: t ) else {
275
279
return nil
276
280
}
277
281
return ThreadInfo ( threadID: info. thread_id,
@@ -328,7 +332,7 @@ extension DarwinRemoteProcess {
328
332
}
329
333
330
334
internal func getThreadID( remotePort: thread_t ) -> UInt64 ? {
331
- guard let remoteThreadObj = getKernelObject ( task: self . task, port: remotePort) else {
335
+ guard let remoteThreadObj = getKernelObject ( task: self . task. value , port: remotePort) else {
332
336
return nil
333
337
}
334
338
return threadInfos. first { $0. kernelObject == remoteThreadObj } ? . threadID
0 commit comments