2015-10-16 11 views
10

iOSアプリケーションがXCodeから直接実行されているかどうかをシミュレータまたはテザリングデバイスでプログラムで判断したいと思います。 hereの-D DEBUGソリューションを試しましたが、Xcodeから切断してアプリケーションを再実行すると、まだデバッグモードであると考えられます。 私は何を私が探していることはあなたが単にCの機能を維持し、スウィフトからそれを呼び出すことができthis functionSwiftアプリケーションがXcodeから実行されているかどうかを検出します

#include <assert.h> 
#include <stdbool.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <sys/sysctl.h> 

static bool AmIBeingDebugged(void) 
    // Returns true if the current process is being debugged (either 
    // running under the debugger or has a debugger attached post facto). 
{ 
    int     junk; 
    int     mib[4]; 
    struct kinfo_proc info; 
    size_t    size; 

    // Initialize the flags so that, if sysctl fails for some bizarre 
    // reason, we get a predictable result. 

    info.kp_proc.p_flag = 0; 

    // Initialize mib, which tells sysctl the info we want, in this case 
    // we're looking for information about a specific process ID. 

    mib[0] = CTL_KERN; 
    mib[1] = KERN_PROC; 
    mib[2] = KERN_PROC_PID; 
    mib[3] = getpid(); 

    // Call sysctl. 
    size = sizeof(info); 
    junk = sysctl(mib, sizeof(mib)/sizeof(*mib), &info, &size, NULL, 0); 
    assert(junk == 0); 

    // We're being debugged if the P_TRACED flag is set. 
    return ((info.kp_proc.p_flag & P_TRACED) != 0); 
} 
+1

スウィフトから、あなたは本当にそれを翻訳する必要はありません。 –

+0

Martin、それは私が入れようとしていた答えです。それを答えとして置き、私はそれをアップヴォートします。 – Knight0fDragon

+0

コードをSwift(ちょっと楽しい)に変換しようとすると、簡単に試してみます:https://gist.github.com/getaaron/8d48489274a873835636。私はそれ以上の時間を持つ必要はありませんが、おそらくそれはあなたを始めさせるでしょう。 –

答えて

33

のスウィフトバージョンだと思います。 How to call Objective-C code from Swiftで与えられたレシピは、純粋なCコードにも適用されます。

しかし、スウィフトにそのコードを変換するために、実際にあまりにも複雑ではありません。

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 
} 

備考:

  • kinfo_proc()ので、ゼロに設定されているすべての フィールドと完全に初期化された構造体を作成しますinfo.kp_proc.p_flag = 0を設定する必要はありません。
  • C intタイプはInt32がスウィフトです。
  • ​​のCコードは、構造体の埋め込みを含むSwiftのstrideOfValue(info) でなければなりません。 sizeofValue(info) の場合、上記のコードは、64ビットデバイス用シミュレータで常にfalseを返します。これは把握するのが最も難しい部分でした。

スウィフト3(Xcodeの8)の更新:

strideofValueと関連する関数はもう存在しない、 彼らはMemoryLayoutに置き換えられている:あなたはCの関数を呼び出すことができます

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 
} 
+2

ニースが 'strideOfValue'で見つけました。私はその違いについて知らなかった。 –

+0

Hey Martin、デバッガを検出するためのObj-CバージョンのXcode 8ソリューションを提供できますか?アップルから提供されたものはもう正常に動作していないようです。ありがとうございました! :-) –

+0

@ HansKnoechel:問題のコードは純粋なCで、Objective-Cから問題なく使用できます。どのように「正しく機能しない」? –

関連する問題