iOS崩溃之dispatch_async

问题

先直接上堆栈

一看到这种堆栈就头痛,但最近正好在学习Apple源码阅读,所以还是静下心来仔细分析。

从堆栈来看,crash的原因应该就是objc_terminate 被调用了。再看是***_dispatch_client_callout*** 调用的,该方法常出现在dispatch_async中,被RunLoop调用,所属的库是libdispatch.dylib。

Apple Open Source下载libdispatch,搜索***_dispatch_client_callout***

复制代码
#undef _dispatch_client_callout
void
_dispatch_client_callout(void *ctxt, dispatch_function_t f)
{
	@try {
		return f(ctxt);
	}
	@catch (...) {
		objc_terminate();
	}
}

这里f 应该就是dispatch_async 传过去的block,底下的objc_terminate很明显就是造成崩溃的直接原因。

而这里被try-catch包裹,那么崩溃的原因已经很明显了,block方法里抛出异常被捕获,触发***objc_terminate(),***造成崩溃。

解决

那么问题来了,如何确定是哪里抛出的异常呢?

首先,常用的NSSetUncaughtExceptionHandler肯定是没法用了,因为这是捕获了异常,主动结束程序。

我们需要的是在异常抛出的那个瞬间,获得当前的堆栈信息。突然想到了,可以使用Xcode提供的Exception Breakpoint。

当我这样设置好断点,满心欢喜地等待结果时,发现又不行。因为应用程序里有太多抛异常的地方了.....一卡一卡地,根本没法运行下去。要是可以跳过断点,并且打印堆栈就好了~

等等,好像这里就提供了这样的功能。我看了看下面的英文,尝试了一下。

可以!!每个抛异常的地方都打印出当前的堆栈,并且跳过。接着触发crash,找到最后打印的堆栈。

这里也可以用lldb命令来实现

相关推荐
2501_916007476 分钟前
不越狱如何查看iOS 应用的详细信息及其文件目录结构
android·macos·ios·小程序·uni-app·cocoa·iphone
handsome091613 分钟前
上传app store和IOS更新版本的实战流程
ios·打包上架
芒鸽2 小时前
macos上Rust 命令行工具鸿蒙化适配完全攻略
macos·rust·harmonyos
山有木兮啊2 小时前
VSCode Remote-SSH 连接Mac卡在初始化VSCode
vscode·macos·ssh
2501_916008893 小时前
无需钥匙串快速创建 iOS 开发 / 发布证书 P12 CSR
android·ios·小程序·https·uni-app·iphone·webview
一个写bug的程序员4 小时前
Mac自启服务关闭方式
macos
梁下轻语的秋缘4 小时前
初学者避坑指南:Mac 虚拟机搭建 Keil5 STM32 环境 + 解决 ST-Link USB Command Error 报错
windows·stm32·macos
天荒地老笑话么4 小时前
macOS 终端:本机隐藏用户名,但 SSH 登录时仍显示(Oh My Zsh + agnoster,更安全)
windows·macos·网络安全
Digitally4 小时前
Mac 屏幕录制工具:12 款 Mac 屏幕录制工具
macos
金山毒霸电脑医生19 小时前
植物大战僵尸融合版下载与安装教程:PC/安卓/iOS 全面指南
游戏·ios·植物大战僵尸·植物大战僵尸融合版·游戏工具