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

Posted

技术标签:

【中文标题】在 LLDB 中获取有关坏内存地址的信息【英文标题】:Getting info about bad memory address in LLDB 【发布时间】:2012-04-08 20:00:18 【问题描述】:

我正在尝试在我的 iPhone 应用程序中调试 EXC_BAD_ACCESS。它在方法调用时崩溃,并且方法的行是EXC_BAD_ACCESS (code=1, address = xxx)

之前,我会使用gdb info malloc-history <xxx> 开始调试,但我在LLDB 中找不到并行命令。

我看到 this 线程说要使用 Instruments,但是当我这样做时,我仍然会崩溃,但我无法弄清楚如何准确判断应用程序在 Instruments 中的崩溃位置。

我只需要弄清楚这块正在崩溃的内存指向的位置。使用 LLDB 或 Instruments 的最佳方法是什么?

【问题讨论】:

你试过打开 NSZombie 吗?这在许多 EXC_BAD_ACCESS 案例中都有帮助! 所以你在设备或模拟器上崩溃了? NSZombie 仅适用于模拟器。 我没有意识到这一点。这就解释了为什么我在使用 NSZombie 时从未发现任何差异。谢谢! 【参考方案1】:

如果您使用工具进行调试,您可以看到 malloc 堆栈。

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

使用工具查找 malloc 历史记录:

    分析您的项目 从仪器列表中选择僵尸 让您的应用触发问题 此时,您应该看到已解除分配的地址,您可以对其进行探索。 此时查看 malloc 历史应该是一件简单的事情。我将具有特定于我正在做的工作的类/项目名称的部分涂黑,但我认为如何获取这些信息的本质和有用性是存在的。

最后一句话

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

*** -[someClass retain]: 消息发送到释放的实例 0x48081fb0 someProject(84051,0xacd902c0) malloc: 记录 malloc 使用标准记录器堆栈到磁盘

我真的很困惑这个retain 是从哪里来的,因为它所破坏的代码没有一个(不在它所在行的getter 或setter 中)。事实证明,当某个对象被 dealloc'ed 时,我没有调用 removeObserver:forKeyPath:。后来在执行过程中,KVO 发生了对一行中的 setter 的操作,这导致程序崩溃,因为 KVO 试图通知一个已经释放的对象。

【讨论】:

有没有办法调试杂散的 kvo 通知?【参考方案2】:

这个问题很容易通过信息丰富的回溯来解决。不幸的是,在最新版本的 ios 和 Xcode 中,有时很难找到好的堆栈跟踪。幸运的是,您可以在 Xcode 中设置“异常断点”,以便在 EXC_BAD_ACCESS 异常之前检查此代码。

    在 Xcode 4 中打开断点导航(这看起来像一个右侧有一个点的矩形) 按左下角的“+”按钮并添加一个“异常断点”。确保为“所有”例外情况中断“On Throw”。

现在您应该在此异常发生之前立即获得完整的回溯。这应该允许您至少将引发此异常的位置归零。

【讨论】:

您的两个答案都非常有帮助,但这就是我最终找出问题所在的方式。现在我只需要修复它:)。感谢大家的帮助!【参考方案3】:

你可以在 lldb 中使用这样的命令:

image lookup --address 0xec509b

您可以在以下位置找到更多命令:LLDB TO GDB COMMAND MAP

【讨论】:

谢谢!我没有遇到僵尸问题,实际上我只是在挖掘CGImageRef 封装的数据。这就是诀窍! @tristan 它没有打印任何东西:(【参考方案4】:

也许为时已晚,但在 LLDB 上需要进一步的帮助:

(lldb) p *(MyClassToPrint*)memory_address

例如

(lldb) p *(HomeViewController*)0x0a2bf700

【讨论】:

以上是关于在 LLDB 中获取有关坏内存地址的信息的主要内容,如果未能解决你的问题,请参考以下文章

内存地址上的观察点

LLDB 的数组地址

c++如何找到进程中的输出表内存地址(OD的bp)

内存地址换算问题!

反汇编查找内存地址

STM32 DMA 内存地址不会设。