I would like to programmatically determine if the iOS app is being run directly from XCode (either in the simulator or on a tethered device). I\'ve tried the -D DEBUG soluti
Clarification: Your C code (and the Swift version below) checks if the program is run under debugger control, not if it's being run from Xcode. One can debug a program outside of Xcode (by calling lldb or gdb directly) and one can run a program from Xcode without debugging it (if the “Debug Executable” checkbox in the scheme setting is off).
You could simply keep the C function and call it from Swift. The recipes given in How to call Objective-C code from Swift apply to pure C code as well.
But it is actually not too complicated to translate that code to Swift:
func amIBeingDebugged() -> Bool {
var info = kinfo_proc()
var mib : [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()]
var size = strideofValue(info)
let junk = sysctl(&mib, UInt32(mib.count), &info, &size, nil, 0)
assert(junk == 0, "sysctl failed")
return (info.kp_proc.p_flag & P_TRACED) != 0
}
Remarks:
kinfo_proc()
creates a fully initialized structure with all
fields set to zero, therefore setting info.kp_proc.p_flag = 0
is not necessary.int
type is Int32
is Swift. sizeof(info)
from the C code has to be strideOfValue(info)
in Swift to include the structure padding. With sizeofValue(info)
the above code always returned false in the Simulator for 64-bit devices. This was the most difficult part to figure out.Update for Swift 3 (Xcode 8):
strideofValue
and the related functions do not exist anymore,
they have been replaced by MemoryLayout
:
func amIBeingDebugged() -> Bool {
var info = kinfo_proc()
var mib : [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()]
var size = MemoryLayout<kinfo_proc>.stride
let junk = sysctl(&mib, UInt32(mib.count), &info, &size, nil, 0)
assert(junk == 0, "sysctl failed")
return (info.kp_proc.p_flag & P_TRACED) != 0
}