2012-03-27 71 views
4

我想在这里做一些小事,但文档建议它应该是可能的。也许LLDB仍然太新了,但是我得到了很多调试器崩溃/死锁,即使没有发生这种情况,它看起来并不像我预期的那样工作。iOS:LLDB多行断点命令不能按预期工作

我想把所有选择器调用的调试包装在一起,以提取特定块代码内的消息调用图。 (我可以解释为什么如果你真的想知道,但它与调试器问题并不真正相关。)

我开始用Xcode断点来开始跟踪事物(对于奖励点,这是发生在辅助线程,但我可以告诉大家,没有,没有任何其他线程正在做它的属性子给该对象的任何访问或任何东西):

[myObject startProcessing]; 

断点触发,和我运行“bt”,只是为了提取:

* thread #5: tid = 0x2203, 0x000277d2 ......... 

然后我做一些事情温和地邪恶:我在objc_msgSend中放置了一个断点,就在它向真实对象选择器调用的指令处。 objc_msgSend的样子:

libobjc.A.dylib`objc_msgSend: 
...(instructions)... 
0x37babfa4: bx  r12 
...(more instructions)... 

(实际上有两个BX电话,但让我们保持简单。)我运行:

breakpoint set -a 0x37babfa4 -t 0x2203 

(TID包括在内,因为我有足够多的麻烦追踪这一个线程,我不需要无关的东西干扰。)

这里是脚本进来的地方。上面描述的设置完全按照我喜欢的方式工作。如果我继续执行,直到断点触发,我可以运行:

frame select 0 
thread step-inst -m this-thread 5 
frame info 
continue 

,效果将是调试器:

  • 移动到objc_msgSend帧由一个指令
  • 步骤,推进它进入它指向的对象选择器框架
  • 显示相关详细信息(对象类型,选择器调用)
  • 恢复执行

在这一点上,我可以反复粘贴这四个命令并复制输出,直到我讨厌自己。

如果,另一方面,我跑:

breakpoint command add -s command 

,并在这些完全相同的命令,一切都休息粘贴。它不会前进到对象选择框。它不显示框架细节,或者至少不是正确的 - 取决于各种调整(见下文),它可能会或可能不会显示“objc_msgSend”作为当前函数。它不会恢复执行。

在这种情况下,如果我能得到这个例子的工作,我会大部分是快乐的。但对于更多奖励积分,我也有蟒蛇试过这个,我宁愿因为这将让更多的复杂的日志记录:

breakpoint command add -s python 
> thread = frame.GetThread() 
> thread.StepInstruction(1) 
> newFrame = thread.GetFrameAtIndex(0) 
> print " " * thread.GetNumFrames() + newFrame.GetFunctionName() 
> process = thread.GetProcess() 
> process.Continue() 
> DONE 

同样没有好处。再次取决于微小的细节,这可能或可能不打印东西(通常是objc_msgSend),但它从不打印正确的东西。它从不向前推进教学。之后它永远不会恢复执行。

再次,如果我手动操作,python版本可以正常工作:如果我等到断点触发,然后运行“脚本”并输入完全相同的行,则按预期工作。有些部件甚至会孤立地工作,例如如果我除了获取进程的部分以及调用process.Continue()并且自动触发这些部分,那么“有效”(意味着我看到lldb提示在它暂停并恢复执行时快速闪烁,通常我后悔这是因为它变成了没有反应,崩溃后不久)。

所以:任何想法?技术尚未准备好,还是我错过了一些可以修复一切的难题?或者我应该完全放弃,只是住在一起的事实,有对象的内部,我将永远不会明白?一些地方...

+0

在使用LLDB进行调试时,SO报告存在其他问题。我知道的一个问题(但找不到裁判文件)报道了切换回GDB时出现的问题。我猜这不是* gasp *成熟的产品。 – 2012-03-27 21:57:50

+0

@PeterM:是的,我从来没有(很多)麻烦gdb是越野车,但它的功能是更多像这样更花哨的东西更多的限制。也许我需要切换回去,然后再尝试几个版本,但... – Archaeopterasa 2012-03-27 23:26:12

回答

3

断点命令无法继续执行,然后再取回控制,至少今天。有很多未解决的问题,如果断点1正在运行该过程,然后命中断点2,会发生什么情况。除了代码库是否可以正确处理嵌套断点(它被设计为......)的整个问题之外,如果断点2决定执行应该停止,这意味着什么?断点1的状态被抛弃了吗?

似乎有点深奥的是担心断点在踩下劣质过程时碰到另一个断点,但除非所有细节都已经制定出来,否则用户很容易在脚中自拍。所以对于今天来说,断点命令可以在断点被击中或继续运行时停止 - 但是没有任何运行一点点和做更多处理的能力。我知道这对于某些任务来说是非常有用的功能,但在完成之前还有很多需要考虑的问题。

在某些情况下,有可能围绕处理它的其他方式...如果你想停止功能parser()只有当它已被称为功能lexer(),很容易把一个断点lexer()一些一些python命令可以将一个堆栈帧放到堆栈中,并查看调用函数是什么。如果不是lexer(),请继续。不过,我认为这不会适用于你想要做的事情。