iOS 堆栈符号解析最佳实践

作者:林伟勋

导语

本文介绍了如何解析 iOS 的 crash 堆栈,分别使用了symbolicatecrash来自动解析整个堆栈,以及使用atos 来解析单个地址的符号。

在 iOS 开发中,解决 crash 问题是比较常见的工作。其中能够解析出符号当然是定位问题的开始。

实际工作中,也有看到很多人其实会卡在解析符号这里,遇到这种情况,可以按照本文中的做法解决。

使用 symbolicatecrash 解析堆栈

symbolicatecrash 是 Xcode 自带的 crash 符号解析工具,可以自动搜索本地符号表,解析整个 crash 堆栈。

确认 Xcode 环境

首先,需要确认 Xcode 的环境,执行以下代码,获取当前 Xcode 的目录。

/usr/bin/xcode-select -print-path 结果应该是:

/Applications/Xcode.app/Contents/Developer/ 如果结果不是上述的路径,则指定一下路径:

sudo /usr/bin/xcode-select -switch /Applications/Xcode.app/Contents/Developer/ 准备好解析堆栈符号的工具:symbolicatecrash

需要先找到 symbolicatecrash 所在的路径,以Xcode 7.3 版本为例,执行:

find /Applications/Xcode.app -name symbolicatecrash -type f 将会返回:

/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash 可以做一个快捷方式:

alias symbolicatecrash='/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash' 需要先配置好DEVELOPER_DIR,否则会报错。如下:

export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer/

开始解析

准备好 dSYM 文件和 app 文件,可以存放在任何位置,只要 mac 系统的 spotlight 能够找到就行。 接着执行

symbolicatecrash xxx.crash

就可以解析符号了。

找不到符号的解决方法

首先,需要确认一下符号表是不是正确的。可以通过以下方式看看符号文件和堆栈是否是对应的 (判断 uuid 是否相同):

dwarfdump --uuid MyApp.app/MyApp
dwarfdump --uuid xxx.app.dSYM/Contents/Resources/DWARF/Resources/MyApp
grep "0x.*com.wison.xxx .*<" NoSymbolsTestxxx.crash

如果不一样,那么说明崩溃堆栈和符号文件对应不上,很可能是搞错版本,或者打包的时候有问题导致符号文件生成不正确。 如果输出一样的 uuid,那么就是对应的,此时 symbolicatecrash 应该可以正常解析符号。 如果还是不能正确解析,那么很可能是 mdfind 自动查找的问题。 Xcode 找符号文件的时候,是通过 mdfind 来找的,比如:

mdfind 'com_apple_xcode_dsym_uuids = *'

该命令会把当前环境下的所有符号文件找出来。 如果你的符号文件不在此列表中,说明 mdfind 找不到我们的符号,

那么就在执行symbolicatecrash的时候显式指定dSYM文件的路径:

symbolicatecrash xxx.crash xxx.dSYM/Contents/Resources/DWARF/MyApp

如果还是不能解析,试一试把 App 文件也指定:

symbolicatecrash xxx.crash xxx.dSYM/Contents/Resources/DWARF/MyApp MyApp.app/MyApp

使用 atos 解析单个符号

有时候我们需要解析单个地址的符号,比如 lr 寄存器的地址对应的符号,就需要用到 atos 用法如下:

atos -arch [armv7 or arm64] -o [BinaryFile or dSYMFile] -l loadAddress address

其中 -arch 指定二进制的架构,比如 armv7,armv7s,arm64 等等。

-o 指定符号文件,可以是 dSYM 文件,也可以是包含了符号表的可执行文件。 -l是加载地址,由于 Xcode 默认打开 PIE 选项,所以加载地址每次都不一样,所以需要指定,可以在 crash 堆栈的 Binary Image 那段看到应用的加载地址。 最后一个参数是需要解析符号的地址。

原文地址:http://wisonlin.github.io/2016/04/09/解析-crash-堆栈/

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏openshift持续集成

jenkins邮件插件中的内容参数设置

众所周知,Jenkins默认提供了一个邮件通知,能在构建失败、构建不稳定等状态后发送邮件。但是它本身有很多局限性,比如它的邮件通知无法提供详细的邮件内容、无法定...

6188
来自专栏WOLFRAM

Wolfram Language 快速编程入门 III

1763
来自专栏逆向技术

16位汇编第一讲简介

                 汇编第一讲 汇编简介 一.什么是汇编   汇编语言他是计算机语言,计算机语言通俗点说就是人类和计算机(也就是CPU)沟通的...

1900
来自专栏Android机器圈

Java虚拟机和Dalvik虚拟机的区别java虚拟机和Dalvik虚拟机的区别

java虚拟机和Dalvik虚拟机的区别 该文章是本人转载的,觉得写的不错,和大家分享一下 Google于2007年底正式发布了Android SDK, 作为 ...

3309
来自专栏上善若水

L010Linux和androidNDK之linux避免僵尸进程,子进程退出的处理

L010Linux和androidNDK之linux避免僵尸进程,子进程退出的处理

1114
来自专栏LinXunFeng的专栏

解决Instruments检测内存泄漏时真机无法定位的问题

1043
来自专栏大魏分享(微信公众号:david-share)

从一张图看Devops全流程

一、持续交付工具链全图 ? 上图源自网络。上图很清晰地列出了CD几个阶段使用的工具。 CD的工具链很长,但并不是每个模块所有工具都那么流行;换言之,我们在每个模...

9829
来自专栏nimomeng的自我进阶

了解和分析iOS Crash Report

翻译自苹果官方文档:Understanding and Analyzing Application Crash Reports

762
来自专栏移动开发之家

快速将Android项目发布的JCenter

demo https://github.com/CarGuo/PublishToJcenter

842
来自专栏栗霖积跬步之旅

关于打包后提示无法连接到mongodb的情况

昨天晚上要和前端联调。 打完jar包后发现无法连接到测试环境的数据库。 就很尴尬,最后发现问题在于mongodb的URI写错了: 正确的URI格式:mongod...

3525

扫码关注云+社区