如何在LLDB断点条件下使用堆栈内容? [英] How do I use stack content in an LLDB breakpoint condition?
问题描述
问题:
我遇到一种情况,我们在启动过程中会播放媒体,并且objc_exception_throw()在此期间命中大约5次,但始终被捕获,并且它在媒体播放器的南部 对象.
I've got a situation where we have a media playback during launch, and objc_exception_throw() hits about 5 times during that period, but is always caught, and it's way south of the media player object.
我已经厌倦了(a)必须手动继续n次,或者(b)必须禁用断点,直到播放完成.
I'm tired of either (a) having to manually continue n times, or (b) having to leave breakpoints disabled until after the playback is complete.
我尝试过的事情:
- 使断点忽略前五次命中(问题:并非总是五次)
- 使用目标作为模块创建我自己的符号断点(问题:什么都没有改变)
我想做什么:
想到的一种解决方案是,在遇到断点时评估堆栈,如果其中列出了特定的方法或函数,则继续执行.但是我不知道该怎么做.
One solution that comes to mind is to evaluate the stack when the breakpoint hits, and continue if a particular method or function is listed therein. But I have no idea how to do this.
也欢迎其他想法.
推荐答案
您使用Python进行此操作.
You do it using Python.
以下内容定义了忽略列表和可以作为命令附加到断点的函数.
The following defines an ignore list and a function you can attach as a command to a breakpoint.
该函数在回溯中获取函数的名称,并将这些名称与忽略列表相交.如果有任何名称匹配,它将继续运行该过程.这样可以有效地避免掉入调试器中不需要的堆栈.
The function grabs the names of functions in the backtrace and set-intersects those names with the ignore list. If any names match, it continues running the process. This effectively skips dropping into the debugger for unwanted stacks.
(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,并在throw_for_real
内部的throw期间进入了调试器.
I tried it against the following file, and it successfully skips the first throw inside recurse_then_throw_and_catch
and drops into the debugger during the throw inside 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中设置脚本命令.)
I imagine you could add this function to your .lldbinit
and then connect it to breakpoints as needed from the console. (I don't think you can set a script command from within Xcode.)
这篇关于如何在LLDB断点条件下使用堆栈内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!