如何调试EXC_BAD_ACCESS错误

30

我收到了一个错误

EXC_BAD_ACCESS代码2,位于0xb0987654处

我想知道如何打印出位于0xb0987654的值?


1
我想你不想打印出那个地址处的值,因为这个地址本身就是你遇到问题的原因。应该问的问题是是什么导致你来到了这里。 - Jay
3个回答

35

若要调试 EXC_BAD_ACCESS,您通常可以通过启用僵尸对象来找到悬空指针的位置。

Xcode

Product > Scheme > Edit Scheme

然后,像下面这样配置

enable zombie objects

AppCode

选择编辑目标,并添加以下环境变量:

NSZombieEnabled=YES

EXC_BAD_ACCESS的另一个原因可能是无限递归,可以通过添加一些日志来发现。

C++更新:

要使用Clang编译器调试C++中的悬空指针,请尝试使用Google的Address Sanitizer (ASAN)


@AdamLee 那这个怎么样?https://dev59.com/gXA75IYBdhLWcg3wm6ex - Jasper Blues
@AdamLee,糟糕,看起来MudFlap只支持gcc,已更新为Clang/llvm。 - Jasper Blues
你有没有在Xcode中使用AddressSanitizer?? 在我尝试的所有Xcode版本中,由Apple提供的“特殊”clang版本都不支持-fsanitize.. - Jay
@Jay 最近还没有尝试过,最近主要使用ObjC。找到任何解决方法或其他方法了吗? - Jasper Blues
1
@JasperBlues 最近我只是使用Instruments模板来处理任何类型的Obj-C内存错误...加上多年的经验,广泛的错误检查以及大量记录不良的C++错误... - Jay

3

看起来你可能正在尝试写入代码页面或其他什么东西?EXC_BAD_ACCESS在/usr/include/mach/exception_types.h中有描述:

#define EXC_BAD_ACCESS          1       /* Could not access memory */
            /* Code contains kern_return_t describing error. */
            /* Subcode contains bad memory address. */

来自kern_return.h文件:

#define KERN_PROTECTION_FAILURE         2
            /* Specified memory is valid, but does not permit the
             * required forms of access.
             */

您可以通过以下方式查看二进制文件中地址的位置:

(lldb) image lookup -va 0xb0987654

但是,你真正需要弄清楚的是谁在尝试写入那里。如果问题很简单,这可能会告诉你出了什么问题,但正如Jasper所建议的那样,这可能是一些使用后释放或其他类似的问题,而坏的操作者在崩溃时已经消失了。guardmalloc有时也可以捕捉到这种错误(您可以在Xcode的运行计划中启用它)。


10
在lldb中运行image lookup -va 0x1586470c4命令,却没有任何输出,甚至没有错误信息。 - Translunar
目前,“image lookup -a”只是打印给定地址上找到的内容,即使在“此地址没有符号”的情况下也是如此,当它找不到与给定地址相关联的任何符号时,LLDB应该真正打印一些错误信息。请使用苹果的错误报告程序或lldb.llvm.org bugzilla提交有关此问题的错误报告。谢谢。 - Jim Ingham

-1

识别导致崩溃的操作。它是否在特定视图控制器的didLoad中崩溃,或在委托方法中或在特定操作中崩溃。这通常有助于找到导致错误的对象。

  • 大多数情况下,“NSZombies”可以帮助识别死亡对象。您可以通过编辑方案,选择Product -> Edit Scheme -> Diagnostics启用NSZombies。
  • 如果仍然找不到根本原因,请始终从子视图控制器向父视图控制器倒退,以查看需要保留哪个对象或需要正确传递哪个消息。
  • 使用静态分析工具和Instruments进行高级调试。

希望这能帮到您。

敬礼, Gison


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