2013-06-04 15 views
7

問題:LLDBブレークポイント条件でスタックコンテンツを使用するにはどうすればよいですか?

私たちは打ち上げ時のメディアの再生を持っている状況、およびobjc_exception_throwを()その期間中に約5倍に当たるが、常にキャッチされ、そしてそれはの南方法だんですメディアプレーヤーオブジェクト

(a)手動でn回続けなければならない、または(b)再生が完了するまでブレークポイントを無効にしなければならないことにうんざりしています。モジュールとしての私のターゲットを使用して独自のシンボリックブレークポイントを作成:(それはありません常に正確に5回の問題は)

    • は、最初の5本のヒットを無視ブレークポイントを作る:私が試した何

      (問題:何も変更)

    私がやりたいこと:

    解決方法の1つは、ブレークポイントがヒットしたときにスタックを評価し、特定のメソッドまたは関数がリストされている場合に継続することです。しかし、私はこれをどうやって行うのか分かりません。

    他のアイデアも歓迎します。

  • 答えて

    12

    あなたはPythonを使用します。

    以下は、無視リストとブレークポイントにコマンドとして追加できる関数を定義しています。

    この関数は、バックトレース内の関数の名前を取得し、それらの名前とignoreリストを交差させます。名前が一致すると、プロセスの実行が継続されます。これは、不要なスタックのデバッガへのドロップを効果的にスキップします。

    (lldb) b objc_exception_throw 
    Breakpoint 1: where = libobjc.A.dylib`objc_exception_throw, address = 0x00000000000113c5 
    (lldb) script 
    Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D. 
    >>> ignored_functions = ['recurse_then_throw_and_catch'] 
    def continue_ignored(frame, bp_loc, dict): 
        global ignored_functions 
        names = set([frame.GetFunctionName() for frame in frame.GetThread()]) 
        all_ignored = set(ignored_functions) 
        ignored_here = all_ignored.intersection(names) 
        if len(ignored_here) > 0: 
         frame.GetThread().GetProcess().Continue() 
    
    quit() 
    
    (lldb) br comm add -F continue_ignored 1 
    (lldb) r 
    

    私は、次のファイルに対してそれを試みたが、それが成功しrecurse_then_throw_and_catch内の最初のスローをスキップし、throw_for_real内部のスロー時にデバッガに落ちます。

    #import <Foundation/Foundation.h> 
    
    void 
    f(int n) 
    { 
        if (n <= 0) @throw [NSException exceptionWithName:@"plugh" reason:@"foo" userInfo:nil]; 
    
        f(n - 1); 
    } 
    
    void 
    recurse_then_throw_and_catch(void) 
    { 
        @try { 
         f(5); 
        } @catch (NSException *e) { 
         NSLog(@"Don't care: %@", e); 
        } 
    } 
    
    void 
    throw_for_real(void) 
    { 
        f(2); 
    } 
    
    int 
    main(void) 
    { 
        recurse_then_throw_and_catch(); 
        throw_for_real(); 
    } 
    

    私はあなたの.lldbinitにこの機能を追加し、コンソールから、必要に応じて、ブレークポイントに接続でき想像します。 PythonのブレークポイントコマンドはFalseを返す場合(私はあなたがXcodeの中からスクリプトコマンドを設定することができるとは思わない。)

    +0

    Damn、dude。私が望むことができる最高の答え。 – MikeyWard

    +0

    良い答え。唯一の注意点は、単に "objc_exception_throw"の上のフレームをチェックするのではなく、スタック上のどこかに 'ignored_functions'のどれかが現れると' continue'することです。 –

    +0

    @JasonMolenda完全に正しい。「スタック上のどこでも」は、「ブレークポイントがヒットしたときにスタックを評価し、特定のメソッドや関数がそこにリストされている場合は、スタックを評価する」という考えに基づいていました。代わりにif frame.GetThread().GetFrameAtIndex(1).GetFunctionName()in ignored_functions:を実行するように適応するのは簡単です。重要な洞察は、ブレークポイントコマンドとしてPython関数を使用することです。 –

    1
    break command add -s python -o "return any('xyz' in f.name for f in frame.thread)" 
    

    を、lldbは続けるだろう。つまり、スタックのanyフレームに文字列'xyz'がある場合は、True(停止する)を返します。それ以外のフレームにその名前がない場合、このany式はFalse(続行する)を返します。

    関連する問題