iOS Crash 分析(文一)- 开始

本文介绍了iOS应用崩溃分析的基础知识,包括UUID、dwarfdump、symbolicatecrash和atosl等名词解释,以及如何获取模拟器和真机的Crash日志。详细阐述了通过Xcode和手动方式获取真机日志的方法,并讨论了使用Xcode和symbolicatecrash脚本进行符号化的步骤。

iOS Crash 分析(文一)- 开始


1. 名词解释

1. UUID

一个字符串,在iOS上每个可执行文件或库文件都包含至少一个UUID。目的是为了唯一识别这个文件。

2. dwarfdump

苹果提供的命令行工具,其中一些功能就是查看可执行文件件或库文件的UUID

3. symbolicatecrash

一个苹果提供的脚本。可以将crash日志符号化为可读的堆栈信息。

4. atosl

苹果提供的命令行工具,可以将crash的base_address和load_address转化为可读的堆栈信息。symbolicatecrash就是使用这个命令来做符号化的。

2.如何获取Crash日志

1.模拟器崩溃

模拟器崩溃后可以在“~/Library/Logs/DiagnosticReports/”下找到crash日志。

2.真机崩溃

1.Xcode获取日志

手机和mac连接后,打开Xcode选择window进入Organizer(快捷方式是 Shift-CMD-2),在 Organizer 窗口上, 选中 Devices 标签栏. 在左侧的导航面板上,选中 Device Logs, 如下图所示:

选择对应设备的Device Logs菜单,就可以看到崩溃日志。
打开图最上边的Device Logs菜单就可以看到mac曾经同步过的iOS设备的崩溃日志。

2.手动获取日志

日志存放的路径 ~/Library/Logs/CrashReporter/MobileDevice/DEVICE_NAME

DEVICE_NAME是你想要查看的设备。
下面是我的终端输出的信息:

➜  DiagnosticReports  pwd
/Users/zhuolaiqiang/Library/Logs/DiagnosticReports
➜  DiagnosticReports  ls
QQ_2014-05-30-132026_Anyhacker.crash            atosl_2014-06-04-151416_Anyhacker.crash         eclipse_2014-05-29-192522_Anyhacker.crash       eclipse_2014-06-02-145714_Anyhacker.crash
SogouInput_2014-05-29-151154_Anyhacker.crash    atosl_2014-06-04-151447_Anyhacker.crash         

3.符号化

1.利用Xcode符号化

app在真机设备上Crash后,我们可以让iOS设备和mac连接,然后打开Xcode选择window进入Organizer(快捷方式是 Shift-CMD-2),在 Organizer 窗口上, 选中对应设备的 Device Logs标签,然后找到对应app日志文件,如图所示:

这样就可以看到已经符号化完毕的日志。

2.利用symbolicatecrash脚本符号化

symbolicatecrash是苹果随Xcode一起提供的专门用来做崩溃日志符号化的脚本工具(perl)。
symbolicatecrash存放路径是
"/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash"。

使用方法是:
symbolicatecrash xx.crash xx.DSYM
xx.crash:需要符号化的崩溃日志文件
xx.DSYM:编译APP时产生的DSYM文件,此文件可以不指定,symbolicatecrash会在硬盘内自动搜索和匹配该文件(前提是你的硬盘内存有这个文件)

### 日志术语分类及中文解释 #### 网络请求相关术语 - **Network Request**:表示应用程序发起的网络请求,例如HTTP请求。日志中通常包含请求地址、方法(GET/POST)、响应状态码等信息。 - **URL Session**:iOS中用于处理网络请求的核心框架之一,日志中可能记录请求开始、结束、错误等状态[^1]。 - **DNS Resolution**:域名解析过程,若出现失败可能影响网络请求的成功率。 - **Timeout**:请求超时,表示网络操作未在指定时间内完成,可能由于服务器无响应或网络延迟导致。 #### 崩溃相关术语 - **Crash**:程序崩溃,通常是由于未捕获的异常或非法操作导致进程终止。 - **Exception**:异常,例如`NSInvalidArgumentException`,表示传入了不合法的参数,可能导致崩溃。 - **Thread 0 Crashed**:主线程崩溃,这是最严重的情况,通常会导致应用立即退出。 - **Last Exception Backtrace**:最后一次异常调用栈,是定位崩溃原因的关键信息,显示了从异常抛出到崩溃发生前的函数调用路径。 - **SIGABRT / EXC_CRASH**:操作系统发送的中止信号,通常由断言失败或未处理的异常触发。 #### 内存相关术语 - **Memory Warning**:内存警告,表示系统检测到设备内存紧张,应用应释放不必要的资源以避免被系统强制终止。 - **OOM (Out Of Memory)**:内存不足,通常表示应用使用的内存超过了系统分配的上限,导致被系统杀掉。 - **VM: malloc**:与内存分配相关的日志条目,用于跟踪动态内存申请和释放情况。 #### 异常与错误处理相关术语 - **Uncaught Exception**:未捕获的异常,表示某个异常没有被任何try-catch块处理,最终导致应用崩溃。 - **Assertion Failure**:断言失败,开发者使用`assert()`等语句进行调试检查时,若条件不满足则触发断言失败并可能导致崩溃。 - **EXC_BAD_ACCESS**:访问非法内存地址,常见于访问已释放的对象指针,也称为“野指针”问题。 #### 用户交互与UI相关术语 - **UIControl**:iOS中用于处理用户交互的基础控件类,日志中可能记录按钮点击、滑动等事件。 - **Touches Ended**:表示用户手指离开屏幕,通常用于处理点击或滑动手势结束的事件。 - **UIAlertController**:用于展示弹窗的控制器,日志中可能出现构造弹窗、添加按钮等行为记录[^3]。 #### 日志级别与输出控制 - **Log Level**:日志级别,用于控制日志输出的详细程度。常见的级别包括DEBUG、INFO、WARNING、ERROR等。 - **ConsoleDestination**:日志输出的目标之一,表示将日志打印到控制台,便于开发者实时查看。 #### 示例:日志级别设置(使用SwiftyBeaver) ```swift import SwiftyBeaver let log = SwiftyBeaver.self log.addDestination(ConsoleDestination()) log.minLevel = .debug // 设置最低日志级别为DEBUG log.debug("This is a debug message") log.info("This is an info message") log.warning("This is a warning message") log.error("This is an error message") ``` 该示例设置了日志级别为`.debug`,因此所有DEBUG及以上级别的日志都会被记录,便于调试过程中区分重要性。 --- ### 示例:典型崩溃日志片段解释 ```plaintext Thread 0 name: Dispatch queue: com.apple.main-thread Thread 0 Crashed: 0 libobjc.A.dylib 0x00000001c3a84a50 objc_msgSend + 8 1 UIKitCore 0x00000001f760bfa0 -[UIApplication sendAction:to:from:forEvent:] + 96 2 UIKitCore 0x00000001f760c2fc -[UIControl sendAction:to:forEvent:] + 76 3 UIKitCore 0x00000001f760c5cc -[UIControl _sendActionsForEvents:withEvent:] + 440 4 UIKitCore 0x00000001f760b7e8 -[UIControl touchesEnded:withEvent:] + 584 5 UIKitCore 0x00000001f763a2d4 -[UIWindow _sendTouchesForEvent:] + 1200 6 UIKitCore 0x00000001f763ac94 -[UIWindow sendEvent:] + 3200 ``` 这段日志描述了崩溃发生在主线程,并展示了调用栈信息。可以看到崩溃点位于`objc_msgSend`函数,这通常意味着调用了一个已经被释放的对象的方法,即“野指针”问题。 --- ### 日志查看工具推荐 - **Xcode Organizer - Crashes标签页**:可以查看从App Store Connect同步过来的崩溃报告,这些报告已经过符号化处理,可以直接看到具体的代码位置。 - **Console App**:macOS内置的控制台应用,可实时查看iOS设备的日志输出,支持关键词过滤和日志级别筛选。 - **Firebase Crashlytics**:自动收集崩溃报告,并提供详细的上下文信息,如设备型号、操作系统版本和堆栈跟踪,适合远程监控和分析--- ### 示例:日志级别设置(使用SwiftyBeaver) ```swift import SwiftyBeaver let log = SwiftyBeaver.self log.addDestination(ConsoleDestination()) log.minLevel = .debug // 设置最低日志级别为DEBUG log.debug("This is a debug message") log.info("This is an info message") log.warning("This is a warning message") log.error("This is an error message") ``` 该示例设置了日志级别为`.debug`,因此所有DEBUG及以上级别的日志都会被记录,便于调试过程中区分重要性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值