如何确定 EXC_BAD_ACCESS 错误是不是是我的代码的错误?

Posted

技术标签:

【中文标题】如何确定 EXC_BAD_ACCESS 错误是不是是我的代码的错误?【英文标题】:How can I figure out if an EXC_BAD_ACCESS error is even the fault of my code?如何确定 EXC_BAD_ACCESS 错误是否是我的代码的错误? 【发布时间】:2011-05-05 06:39:25 【问题描述】:

我正在用 C++ 在 Macintosh 上编写代码。长话短说,它与 TWAIN 交互。

我们根据 TWAIN 标准进行编码,并且使用我们用于开发的主要平板扫描仪,它可以完美运行。使用其他扫描仪,就没有那么多了。

特别是,我正在使用的第二个扫描仪往往会在随机点和间隔处崩溃。

例如,它有时会在这样的一行上崩溃

OSErr err = DSM_Entry(&mAppIdentity,
                      NULL, 
                      DG_CONTROL, 
                      DAT_IDENTITY, 
                      MSG_OPENDS, 
                      (TW_MEMREF)&mDSIdentity);

DSM_Entry 是对 TWAIN 函数的别名系统调用(我认为这是术语)。mDSIdentitymAppIdentity 都是 TW_IDENTITY 结构,是 TWAIN 的东西。其中一个识别我们的应用程序,另一个是获取数据源(TWAIN 扫描仪)的值。 DG_ 参数是“操作三元组”,它们是 #define 值,在这种组合中,代表特定操作 - 在这种情况下,从数据源管理器打开数据源

有时这行得通,有时却失败了。有时它在第三次扫描时失败,有时在第二次扫描时失败,有时在第一次扫描时失败。就像我在第一个扫描仪中所说的那样,它工作得很好,而在其他扫描仪中,它会以这些随机间隔死掉。

在调试器中,我看到的消息各不相同,但我通常看到的一件事是EXC_BAD_ACCESS

Program received signal:  “EXC_BAD_ACCESS”.
Cannot access memory at address 0x17f3ccac

一些搜索表明这往往发生在 Apple 平台上(iPhone 和 Obj-C 经常受到打击)只要内存方面发生了不好的事情,比如可能使用取消引用的指针。与内存相关似乎支持随机性,但我不知道哪里出了问题,特别是因为它工作时与不工作时似乎没有什么不同(即,在断点处确切的 DSM_Entry 调用崩溃的值似乎与之前非常相似的 DSM_Entry 调用相同,工作正常),所涉及变量的内存位置与错误中的内存地址不匹配,@987654333 @ 应该在失败时返回一个代码,但在这种情况下,它只是让一切崩溃,异常处理没有任何效果。

根据 Apple 开发人员的说法,EXC_BAD_ACCESS 及其同类错误是最难调试的错误,这让我感到有些欣慰,但我不知道该怎么做。由于我们正在与我们没有编写的 TWAIN 驱动程序交互,因此错误甚至可能不在我们的代码中。这让我询问了state of TWAIN on the Mac(因为我们在 Windows 中没有遇到这么多麻烦),但我们已经对至少四个不同的扫描仪制造商进行了测试,我很难相信他们都可能是错的。

此外,我在 Xcode 中编译时打开了所有警告,但仍然没有关于正在发生的事情的任何线索(或其他警告)。

对于解决EXEC_BAD_ACCESS 错误,或者如何确定这是否是我的代码的错误,是否有任何其他建议?

【问题讨论】:

你能把它隔离成一小段代码,以确保你得到同样的错误吗?这将帮助您确定错误是否在您身上。 @Nathan S.:不是真的。我的意思是,它总是发生在这些 DSM_Entry 调用之一上(并且由于与 TWAIN 通信的性质,有很多调用),但并不总是同一个,有时根本不会。 我自己没有使用过 TWAIN,但是如果您编写一个只进行 DSM_Entry 调用并且不处理任何其他数据的小程序会发生什么?如果您的程序足够小,您可以快速验证问题一定出在 API 中。然后你只需要找到神奇的解决方法来让事情正常进行。如果您还没有,我建议您在 Apple 的邮件列表中询问。 【参考方案1】:

如果您在 GDB 中运行,您应该会看到一个堆栈跟踪,它会为您提供一些很好的线索,但它不会立即告诉您问题是否是您留下了不好的东西。

您也可以尝试启用 malloc 调试。

【讨论】:

是的,我一直在 GDB 中运行,尽管在调试模式下运行它,我没有得到堆栈跟踪,它没有去除符号等。这可能会让人相信它是一个错误别人的代码。不知道。不过感谢 malloc 调试提示,我会尝试一下。 你是什么意思'没有回溯'。它没有停止,或者它没有显示任何有趣的东西? 连接 Xcode 调试器后,它会停止冷却,我从中得到的只是两行,就像我在上面粘贴的那样。没有堆栈跟踪。如果我没有连接到调试器,程序就会崩溃。 我自己会在命令级别使用 gdb 进行尝试,以防 xcode 恶作剧。【参考方案2】:

我遇到了同样的问题,只有在我尝试打开一些扫描仪时应用程序才会崩溃 (MSG_OPENDS)。在某些扫描仪 (usb) 上调用 MSG_OPENDS 时,应用程序分配了大量内存,这有时会导致崩溃。

我花了很多时间认为这是代码中的错误,但是当我在 TwainClientCocoa 中测试相同的代码时,它运行良好。

最后,在浪费了几个小时之后,我设法修复它.. 通过从项目的 plist 中设置 CFBundleIconFile

MSG_OPENDS 失败时,它会显示一个警告框,其中还包含应用程序图标。我的猜测是问题来自该警报(Twain.framework 中的错误.. 或 Twain 使用的其他框架)。

【讨论】:

以上是关于如何确定 EXC_BAD_ACCESS 错误是不是是我的代码的错误?的主要内容,如果未能解决你的问题,请参考以下文章

确定没有 NSZombie 的 EXC_BAD_ACCESS 的根本原因?

如何调试 EXC_BAD_ACCESS 错误

删除coredata列表项时SwiftUI App崩溃EXC_BAD_ACCESS错误

程序接收信号:带有Core Data的“EXC_BAD_ACCESS”

iOS UIAlertView 给出 EXC_BAD_ACCESS

iOS:重置 UIPickerView EXC_BAD_ACCESS 错误