你可以使用Python来完成这个任务。
以下是一个忽略列表和一个可附加为断点命令的函数定义。
该函数获取回溯中的函数名称,并将这些名称与忽略列表进行交集设置。如果有任何名称匹配,则继续运行进程。这有效地跳过了不需要调试的堆栈。
(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
中,然后根据需要从控制台连接到断点。(我认为你不能在Xcode内部设置脚本命令。)
ignored_functions
,它将会continue
,而不仅仅是检查“上面”的objc_exception_throw
帧。 - Jason Molendaif frame.GetThread().GetFrameAtIndex(1).GetFunctionName() in ignored_functions:
。关键的洞察力是使用Python函数作为断点命令。 - Jeremy W. Sherman