在LLDB中获取有关错误内存地址的信息

25

我正在尝试调试我的iPhone应用程序中的EXC_BAD_ACCESS错误。它在一个方法调用上崩溃,并且在该方法的行上出现了EXC_BAD_ACCESS(code=1,address=xxx)

以前,我会使用gdb info malloc-history <xxx>来开始调试,但我在LLDB中找不到相应的命令。

我看到了这个帖子,说要使用Instruments,但是当我这样做时,我仍然收到崩溃报告,但我无法确定在Instruments中精确定位应用程序崩溃的位置。

我只需要找出导致崩溃的内存块指向了哪里。最好的方法是使用LLDB或Instruments吗?


1
你尝试过打开NSZombie吗?它有助于解决许多EXC_BAD_ACCESS问题! - calimarkus
你的设备或模拟器出现了崩溃?NSZombie只能在模拟器上使用。 - Eimantas
我没有意识到这一点。这就解释了为什么我在使用NSZombie时从未看到任何区别。谢谢! - Ross Kimes
4个回答

44

使用instruments进行调试,您可以查看malloc堆栈。

我遇到了和你一样的问题,同样想知道在使用lldb时如何获取malloc历史记录。不幸的是,我没有像在gdb中找到的malloc-history这样好用的命令。老实说,我只是换了我的调试器,但我觉得这很烦人,因为我不应该这样做。

使用instruments查找malloc历史记录的方法:

  1. 对项目进行性能分析
  2. 从仪表列表中选择Zombies enter image description here
  3. 让您的应用程序触发问题
  4. 此时,您应该会看到已经被释放的地址,并且您可以浏览它。 enter image description here 此时查看malloc历史记录应该是一个简单的事情。 我黑掉了具有特定于我正在进行的工作的类/项目名称的部分,但我认为获得此信息的本质和有用性是存在的。

最后一句话

我遇到的问题产生了以下消息:

*** -[someClass retain]: message sent to deallocated instance 0x48081fb0 someProject(84051,0xacd902c0) malloc: recording malloc stacks to disk using standard recorder

我真的很困惑为什么会出现这个retain,因为它断在的代码中没有一个(不在该行的getter或setter中)。后来发现,在某个对象被dealloc时,我没有调用removeObserver:forKeyPath:。执行后面的KVO时,由于KVO试图通知已经释放的对象,程序崩溃了。


有没有一种方法可以调试偶发的 KVO 通知? - Nav

38

通过详细的回溯信息,这个问题很容易解决。不幸的是,最新版本的iOS和Xcode有时会很难获得良好的堆栈跟踪信息。幸运的是,您可以在Xcode中设置“异常断点”,以允许您在EXC_BAD_ACCESS异常发生前检查此代码。

  1. 在Xcode 4中打开断点导航(它看起来像一个带有右边点的矩形)
  2. 在左下角按“+”按钮添加“异常断点”。确保您在“All”异常上“On Throw”中断。

现在,在此异常发生之前,您应该可以立即获得完整的回溯信息。这应该至少让您确定此异常抛出的位置。


你们两个的回答都非常有帮助,但是这就是我最终找出问题所在的方法。现在我只需要修复它 :). 感谢所有的帮助! - Ross Kimes

15

您可以在lldb中使用以下命令:

image lookup --address 0xec509b

您可以在LLDB TO GDB COMMAND MAP找到更多命令。


谢谢!我没有遇到僵尸问题,事实上我只是在挖掘由CGImageRef封装的数据。这就是诀窍! - Richard J. Ross III
19
@tristan 没有任何打印输出 :( - Nikita P

10

也许有点晚了,但对于LLDB的进一步帮助:

(lldb) p *(MyClassToPrint*)memory_address

例如。

(lldb) p *(HomeViewController*)0x0a2bf700

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接