热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

什么是EXC_BAD_ACCESS以及如何调试

某些时候,你可能会遇到由EXC_BAD_ACCESS引起的崩溃。在这片文章中,你将学会什么是EXC_BAD_ACCESS,以及它是由什么引起的。我也将提出一些解决由EXC_BAD_ACCESS引

某些时候,你可能会遇到由EXC_BAD_ACCESS引起的崩溃。在这片文章中,你将学会什么是EXC_BAD_ACCESS,以及它是由什么引起的。我也将提出一些解决由EXC_BAD_ACCESS引起的bug的技巧。

什么是EXC_BAD_ACCESS?

一旦你理解了EXC_BAD_ACCESS的根本原因,你会更好地理解它这个含义模糊的名称。这里有一个简单的解释和一个更加专业的解释。让我们首先以这个简单的解释开始吧。

保持简单

无论何时你遇到了EXC_BAD_ACCESS,那就意味着你正在发送一个消息给一个对象,而这个对象已经被释放掉了。这是最常见的情况,但是下面来看看更多的解释。

真正含义

专业的解释有一些复杂。在C和Objective-C中,经常处理指针。指针无非是存储另一个变量的内存地址的变量。当你发送一个消息给一个对象,那么指向这个对象的指针需要被引用。这意味着,你取得这个指针指向的内存地址而且访问那块内存的值。

当那块内存不再与你的应用程序映射,或者,换一种说法,那块内存不再以你所期许的方式被使用,那么,就有可能无法访问到那一块内存。当这种情况发生的时候,内核发送异常( EXC ),表明你的应用程序无法访问到那块内存(BAD ACCESS)。

概括起来就是:当你遇到EXC_BAD_ACCESS时,意味着你在尝试向一块内存发送消息,而这块内存无法执行这个消息。

然而,有时候,EXC_BAD_ACCESS是由一个corrupt pointer(即野指针)引起的。每当你的应用程序程序尝试去引用一个corrupt pointer指针时,内核都会抛出一个异常。

注:corrupt pointer:可以理解为『野指针』。指的是:指向一个已删除的对象或未申请访问受限内存区域的指针。与空指针不同,野指针无法通过简单地判断是否为 NULL避免,而只能通过养成良好的编程习惯来尽力减少。对野指针进行操作很容易造成程序错误。

调试EXC_BAD_ACCESS

调试EXC_BAD_ACCESS可能是棘手和令人沮丧的。显示,现在EXC_BAD_ACCESS对你来说不再是那么困难的事情了。

你需要了解的第一件事情是,一旦内存块无法被访问到,你的应用程序就会崩溃。这就是使调试EXC_BAD_ACCESS这么困难的原因。

同样的,当你引用野指针时,情况就糟糕了。

Zombies

虽然僵尸在过去的几年中才得到普及,但是,在Xcode中以及出现十多年了。『僵尸』这个名称听起来可能有些戏剧化,但是,这对于解释我们是如何调试EXC_BAD_ACCESS来说,是一个体现其特性的伟大的名字。

在Xcode中,你可以启用僵尸对象(zombie objects),这意味着,被释放的对象作为『僵尸』来被保持。换句话说,被释放的对象为了调试程序而被保持活跃。这没有什么神奇的作用。如果你将消息发送给一个僵尸对象,你的应用程序仍然会得到一个EXC_BAD_ACCESS的崩溃。

为什么启用zombie是有用的?让EXC_BAD_ACCESS难以调试的原因是:你不知道你的应用程序尝试去访问的对象是什么。在多种情况下,僵尸对象能够解决这个问题。通过使被释放的对象保持活跃,Xcode能够告诉你应用程序试图访问的对象,并使问题的检索更加简单。

在Xcode中启用Zombies很简单。注意,你的Xcode版本不同可能导致方法不同。以下方法适用于Xcode 6 和Xcode 7.选择工具条中的Product-> 选择 Scheme -> 选择 Edit Scheme。或者使用快捷方式Command+<

选择左侧的Run,打开顶部标签中的Diagnotics(诊断),勾选复选框Enable Zombie Objects。
此处输入图片的描述

如果现在遇到EXC_BAD_ACCESS,Xcode控制台的输出会给你一个从哪里开始检索错误的更好的建议。看看下面的例子:

2015-08-12 06:31:55.501 Debug[2371:1379247] -[ChildViewController respondsToSelector:] message sent to deallocated instance 0x17579780

在上面的例子中,Xcode是在告诉我们,这个消息respondsToSelector:被发送给一个僵尸对象。然而,僵尸对象不再是ChildViewController类的一个实例对象。之前分配给ChildViewController实例对象的内存块不再与你的应用程序所映射。这对你认识问题的根本原因有所帮助。

不幸的是,僵尸对象不能解决你所遇到的任何由EXC_BAD_ACCESS所引起的崩溃。如果僵尸对象不能解决你的问题,那么试着去做一些分析。

剖析

如果僵尸对象不能帮助你,那么根本原因则是很重要的。这种情况下,你应该仔细看看你的应用程序崩溃时正在执行的代码。这个过程有可能是耗时而麻烦的。

为了帮你找到你的代码中得问题,你可以让Xcode分析你的代码,以帮你找到问题区间。注意,Xcode分析你的项目,可能会指出它遇到的任何一个潜在的问题。

选择Product->Analyze,或者快捷方式Shift+Command+B,来启用Xcode对你的项目的分析。

这可能消耗Xcode几分钟时间,但是,当它完成的时候,你会在左侧的问题导航器中看到问题清单。通过分析发现的问题以蓝色高亮显示。
此处输入图片的描述

当你点击一个问题时,Xcode定位到需要你注意的那块代码。需要注意的是,Xcode只是提出建议,某些时候,有可能问题是不相干的,或者不需要你去解决的。
此处输入图片的描述

如果你不能找到引起EXC_BAD_ACCESS的bug,那么仔细检查Xcode在分析过程中找到的问题就很重要了。

结论

EXC_BAD_ACCESS是开发人员共同面临的挫折,这是手动内存管理所特有的东西。自推出ARC之后,内存管理相关的问题出现的频率比较低了,但是,它们并没有消失。

本篇文章翻译自:http://code.tutsplus.com/tutorials/what-is-exc_bad_access-and-how-to-debug-it–cms-24544


推荐阅读
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • 开发技巧:在Interface Builder中实现UIButton文本居中对齐的方法与步骤
    开发技巧:在Interface Builder中实现UIButton文本居中对齐的方法与步骤 ... [详细]
  • 在《Cocos2d-x学习笔记:基础概念解析与内存管理机制深入探讨》中,详细介绍了Cocos2d-x的基础概念,并深入分析了其内存管理机制。特别是针对Boost库引入的智能指针管理方法进行了详细的讲解,例如在处理鱼的运动过程中,可以通过编写自定义函数来动态计算角度变化,利用CallFunc回调机制实现高效的游戏逻辑控制。此外,文章还探讨了如何通过智能指针优化资源管理和避免内存泄漏,为开发者提供了实用的编程技巧和最佳实践。 ... [详细]
  • 本文深入解析了WCF Binding模型中的绑定元素,详细介绍了信道、信道管理器、信道监听器和信道工厂的概念与作用。从对象创建的角度来看,信道管理器负责信道的生成。具体而言,客户端的信道通过信道工厂进行实例化,而服务端则通过信道监听器来接收请求。文章还探讨了这些组件之间的交互机制及其在WCF通信中的重要性。 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • 本文探讨了如何在C#应用程序中通过选择ComboBox项从MySQL数据库中检索数据值。具体介绍了在事件处理方法 `comboBox2_SelectedIndexChanged` 中可能出现的常见错误,并提供了详细的解决方案和优化建议,以确保数据能够正确且高效地从数据库中读取并显示在界面上。此外,还讨论了连接字符串的配置、SQL查询语句的编写以及异常处理的最佳实践,帮助开发者避免常见的陷阱并提高代码的健壮性。 ... [详细]
  • Squaretest:自动生成功能测试代码的高效插件
    本文将介绍一款名为Squaretest的高效插件,该工具能够自动生成功能测试代码。使用这款插件的主要原因是公司近期加强了代码质量的管控,对各项目进行了严格的单元测试评估。Squaretest不仅提高了测试代码的生成效率,还显著提升了代码的质量和可靠性。 ... [详细]
  • 在使用 SQL Server 时,连接故障是用户最常见的问题之一。通常,连接 SQL Server 的方法有两种:一种是通过 SQL Server 自带的客户端工具,例如 SQL Server Management Studio;另一种是通过第三方应用程序或开发工具进行连接。本文将详细分析导致连接故障的常见原因,并提供相应的解决策略,帮助用户有效排除连接问题。 ... [详细]
  • 在处理数据库中所有用户表的彻底清除时,目前尚未发现单一命令能够实现这一目标。因此,需要采用一种较为繁琐的方法来逐个删除相关表及其结构。具体操作可以通过编写PL/SQL脚本来实现,该脚本将动态生成并执行删除表的SQL语句。尽管这种方法相对复杂,但在缺乏更简便手段的情况下,仍是一种有效的解决方案。未来或许可以通过数据库管理工具或更高版本的数据库系统提供更简洁的处理方式。 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 在Cisco IOS XR系统中,存在提供服务的服务器和使用这些服务的客户端。本文深入探讨了进程与线程状态转换机制,分析了其在系统性能优化中的关键作用,并提出了改进措施,以提高系统的响应速度和资源利用率。通过详细研究状态转换的各个环节,本文为开发人员和系统管理员提供了实用的指导,旨在提升整体系统效率和稳定性。 ... [详细]
  • MATLAB字典学习工具箱SPAMS:稀疏与字典学习的详细介绍、配置及应用实例
    SPAMS(Sparse Modeling Software)是一个强大的开源优化工具箱,专为解决多种稀疏估计问题而设计。该工具箱基于MATLAB,提供了丰富的算法和函数,适用于字典学习、信号处理和机器学习等领域。本文将详细介绍SPAMS的配置方法、核心功能及其在实际应用中的典型案例,帮助用户更好地理解和使用这一工具箱。 ... [详细]
  • C++ 异步编程中获取线程执行结果的方法与技巧及其在前端开发中的应用探讨
    本文探讨了C++异步编程中获取线程执行结果的方法与技巧,并深入分析了这些技术在前端开发中的应用。通过对比不同的异步编程模型,本文详细介绍了如何高效地处理多线程任务,确保程序的稳定性和性能。同时,文章还结合实际案例,展示了这些方法在前端异步编程中的具体实现和优化策略。 ... [详细]
  • 在使用 Qt 进行 YUV420 图像渲染时,由于 Qt 本身不支持直接绘制 YUV 数据,因此需要借助 QOpenGLWidget 和 OpenGL 技术来实现。通过继承 QOpenGLWidget 类并重写其绘图方法,可以利用 GPU 的高效渲染能力,实现高质量的 YUV420 图像显示。此外,这种方法还能显著提高图像处理的性能和流畅性。 ... [详细]
  • 数字图书馆近期展出了一批精选的Linux经典著作,这些书籍虽然部分较为陈旧,但依然具有重要的参考价值。如需转载相关内容,请务必注明来源:小文论坛(http://www.xiaowenbbs.com)。 ... [详细]
author-avatar
mobiledu2502869373
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有