@@ -101,31 +101,13 @@ class Target {
101101
102102 var mcontext : MContext
103103
104- static func getParentTask( ) -> task_t ? {
105- var ports : mach_port_array_t ? = nil
106- var portCount : mach_msg_type_number_t = 0
107-
108- // For some reason, we can't pass a task read port this way, but we
109- // *can* pass the control port. So do that and then ask for a read port
110- // before immediately dropping the control port from this process.
111-
112- let kr = mach_ports_lookup ( mach_task_self_, & ports, & portCount)
104+ static func getTask( pid: pid_t ) -> task_t ? {
105+ var port : task_t = 0
106+ let kr = task_read_for_pid ( mach_task_self_, pid, & port)
113107 if kr != KERN_SUCCESS {
114108 return nil
115109 }
116-
117- if let ports = ports, portCount != 0 {
118- var taskPort : mach_port_t = 0
119- let kr = task_get_special_port ( ports [ 0 ] , TASK_READ_PORT, & taskPort)
120- if kr != KERN_SUCCESS {
121- mach_port_deallocate ( mach_task_self_, ports [ 0 ] )
122- return nil
123- }
124- mach_port_deallocate ( mach_task_self_, ports [ 0 ] )
125- return task_t ( taskPort)
126- } else {
127- return nil
128- }
110+ return port
129111 }
130112
131113 static func getProcessName( pid: pid_t ) -> String {
@@ -141,15 +123,40 @@ class Target {
141123 }
142124 }
143125
126+ static func isPlatformBinary( pid: pid_t ) -> Bool {
127+ var flags = UInt32 ( 0 )
128+
129+ return csops ( pid,
130+ UInt32 ( CS_OPS_STATUS) ,
131+ & flags,
132+ MemoryLayout< UInt32> . size) != 0 ||
133+ ( flags & UInt32 ( CS_PLATFORM_BINARY | CS_PLATFORM_PATH) ) != 0
134+ }
135+
144136 init ( crashInfoAddr: UInt64 , limit: Int ? , top: Int , cache: Bool ) {
145137 pid = getppid ( )
146- if let parentTask = Self . getParentTask ( ) {
147- task = parentTask
148- } else {
149- print ( " swift-backtrace: couldn't fetch parent task " , to: & standardError)
138+
139+ if Self . isPlatformBinary ( pid: pid) {
140+ /* Exit silently in this case; either
141+
142+ 1. We can't call csops(), because we're sandboxed, or
143+ 2. The target is a platform binary.
144+
145+ If we get killed, that is also fine. */
150146 exit ( 1 )
151147 }
152148
149+ // This will normally only succeed if the parent process has
150+ // the com.apple.security.get-task-allow privilege. That gets set
151+ // automatically if you're developing in Xcode; if you're developing
152+ // on the command line or using SwiftPM, you will need to code sign
153+ // your binary with that entitlement to get this to work.
154+ guard let parentTask = Self . getTask ( pid: pid) else {
155+ exit ( 1 )
156+ }
157+
158+ task = parentTask
159+
153160 reader = RemoteMemoryReader ( task: __swift_task_t ( task) )
154161
155162 name = Self . getProcessName ( pid: pid)
0 commit comments