Xcode 如何在LLDB断点条件下使用堆栈内容?

Xcode 如何在LLDB断点条件下使用堆栈内容?,xcode,lldb,Xcode,Lldb,问题: 我遇到过这样一种情况:我们在启动期间播放媒体,在这段时间内,objc_exception_throw()点击了大约5次,但总是被捕捉到,而且它位于媒体播放器对象的南部 我厌倦了(a)必须手动继续n次,或者(b)必须在播放完成之前禁用断点 我所尝试的: 使断点忽略前五次命中(问题:它并不总是正好五次) 使用我的目标作为模块创建我自己的符号断点(问题:没有更改) 我想做什么: 想到的一个解决方案是在断点到达时计算堆栈,如果其中列出了特定的方法或函数,则继续。但我不知道怎么做 其他想法也很

问题:

我遇到过这样一种情况:我们在启动期间播放媒体,在这段时间内,objc_exception_throw()点击了大约5次,但总是被捕捉到,而且它位于媒体播放器对象的南部

我厌倦了(a)必须手动继续n次,或者(b)必须在播放完成之前禁用断点

我所尝试的:

  • 使断点忽略前五次命中(问题:它并不总是正好五次)
  • 使用我的目标作为模块创建我自己的符号断点(问题:没有更改)
我想做什么:

想到的一个解决方案是在断点到达时计算堆栈,如果其中列出了特定的方法或函数,则继续。但我不知道怎么做


其他想法也很受欢迎。

您可以使用Python来实现

下面定义了一个忽略列表和一个可以作为命令附加到断点的函数

函数获取回溯中函数的名称,并将这些名称与忽略列表相交。如果任何名称匹配,它将继续运行该进程。这有效地避免了将不需要的堆栈放入调试器

(lldb)b objc_异常_抛出
断点1:where=libobjc.A.dylib`objc_exception_throw,address=0x00000000000113c5
(lldb)脚本
Python交互式解释器。要退出,请键入“退出()”、“退出()”或Ctrl-D。
>>>忽略的函数=['recurse\u然后\u throw\u和\u catch']
def continue_忽略(帧、bp_loc、dict):
全局函数
name=set([frame.GetThread()]中的frame的[frame.GetFunctionName())
所有\u忽略=设置(忽略的\u函数)
忽略这里的\u=所有\u忽略。交叉点(名称)
如果len(此处忽略)>0:
frame.GetThread().GetProcess().Continue()
退出
(lldb)br comm add-F continue\u忽略1
(lldb)r
我对下面的文件进行了尝试,它成功地跳过了
recurse\u内的第一次抛出,然后跳过了\u-throw\u和\u-catch
,并在抛出
throw\u for \u real
的过程中放入调试器

#导入
无效的
f(整数n)
{
如果(n)

如果python断点命令返回
False
,lldb将继续运行。也就是说:如果堆栈中的
任何
帧的名称中包含字符串
'xyz'
,则返回
True
(停止)。否则,如果没有帧具有该名称,该
任何
表达式将返回
False
(继续运行).

该死,老兄。这是我所希望的最好的答案。回答很好。唯一要注意的是,如果堆栈上的任何一个
忽略的函数出现,而不是仅仅检查“上面”的帧
objc\u exception\u throw
@JasonMolenda完全正确。“堆栈上的任何地方”这是我根据“当断点命中时评估堆栈,如果其中列出了特定的方法或函数,则继续”。如果frame.gethread().GetFrameAtIndex(1.GetFunctionName(),则适应执行
if frame.gethread().GetFrameAtIndex()将很简单在被忽略的函数中:
。关键的细节是使用Python函数作为断点命令。还要注意的是,从Xcode 5的lldb开始,lldb检查Python断点命令的返回值,如果它们返回的布尔值为False,lldb将从断点处继续。也许这比必须校准要简单一些手动“continue”。这也意味着,如果同时命中两个断点(这在线程代码中确实发生),则只有当两个断点命中都希望继续时,lldb才会继续。
break command add -s python -o "return any('xyz' in f.name for f in frame.thread)"