あなたは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の中からスクリプトコマンドを設定することができるとは思わない。)
Damn、dude。私が望むことができる最高の答え。 – MikeyWard
良い答え。唯一の注意点は、単に "objc_exception_throw"の上のフレームをチェックするのではなく、スタック上のどこかに 'ignored_functions'のどれかが現れると' continue'することです。 –
@JasonMolenda完全に正しい。「スタック上のどこでも」は、「ブレークポイントがヒットしたときにスタックを評価し、特定のメソッドや関数がそこにリストされている場合は、スタックを評価する」という考えに基づいていました。代わりにif frame.GetThread().GetFrameAtIndex(1).GetFunctionName()in ignored_functions:を実行するように適応するのは簡単です。重要な洞察は、ブレークポイントコマンドとしてPython関数を使用することです。 –