分析iOS Crash文件:符号化iOS Crash文件的3种方法

简介:

当你的应用提交到AppStore或者各个渠道之后,请问你多久会拿到crash文件?你如何分析crash文件的呢?


上传crash文件

你的应用应当有模块能够在应用程序crash的时候上传crash信息。 要么通过用户反馈拿到crash文件,要么借助自己或第3方的crash上传模块拿到crash文件。

今天要分析的场景是你拿到用户的.crash文件之后,如何符合化crash文件(Symbolicating crash logs)的3种方法。帮助尽快找到crash原因。


crash文件例子

crash文件的部分内容:

Last Exception Backtrace:

  • 0 CoreFoundation 0x30acaf46 exceptionPreprocess + 126

  • 1 libobjc.A.dylib 0x3af0b6aa objc_exception_throw + 34

  • 2 CoreFoundation 0x30a0152e -[__NSArrayM objectAtIndex:] + 226

  • 3 appName 0x000f462a 0x4000 + 984618

  • 4 appName 0x00352aee 0x4000 + 3468014

  • 18 appName 0x00009404 0x4000 + 21508

大家一眼就能看到:

  • 2 CoreFoundation 0x30a0152e -[__NSArrayM objectAtIndex:] + 226

这一行有问题。

但是,第3行和第4行的:

  • 3 appName 0x000f462a 0x4000 + 984618

  • 4 appName 0x00352aee 0x4000 + 3468014

并没有指出到底是app的那个模块导致的问题,如何排查呢?


有如下3种方法


方法1 使用XCode

这种方法可能是最容易的方法了。

要使用Xcode符号化 crash log,你需要下面所列的3个文件:

  • crash报告(.crash文件)
  • 符号文件 (.dsymb文件)
  • 应用程序文件 (appName.app文件,把IPA文件后缀改为zip,然后解压,Payload目录下的appName.app文件), 这里的appName是你的应用程序的名称

把这3个文件放到同一个目录下,打开Xcode的Window菜单下的organizer,然后点击Devices tab,然后选中左边的Device Logs。

然后把.crash文件拖到Device Logs或者选择下面的import导入.crash文件。

这样你就可以看到crash的详细log了。 如下图:


方法2 使用命令行工具symbolicatecrash

有时候Xcode不能够很好的符号化crash文件。我们这里介绍如何通过symbolicatecrash来手动符号化crash log。

在处理之前,请依然将“.app“, “.dSYM”和 ".crash"文件放到同一个目录下。现在打开终端(Terminal)然后输入如下的命令:

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

然后输入命令:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash appName.crash appName.app > appName.log

现在,符号化的crash log就保存在appName.log中了。


方法3 使用命令行工具atos

如果你有多个“.ipa”文件,多个".dSYMB"文件,你并不太确定到底“dSYMB”文件对应哪个".ipa"文件,那么,这个方法就非常适合你。

特别当你的应用发布到多个渠道的时候,你需要对不同渠道的crash文件,写一个自动化的分析脚本的时候,这个方法就极其有用。

这里先介绍一个概念:UUID

什么是UUID

每一个可执行程序都有一个build UUID来唯一标识。Crash日志包含发生crash的这个应用(app)的 build UUID以及crash发生的时候,应用加载的所有库文件的[build UUID]。

那如何知道crash文件的UUID呢?

可以用:

grep "appName armv" *crash

或者

grep --after-context=2 "Binary Images:" *crash

可以得到类似如下的结果:

appName.crash-0x4000 - 0x9e7fff appName armv7 <8bdeaf1a0b233ac199728c2a0ebb4165> /var/mobile/Applications/A0F8AB29-35D1-4E6E-84E2-954DE7D21CA1/appName.crash.app/appName

(请注意这里的0x4000,是模块的加载地址,后面用atos的时候会用到)

如何找到app的UUID

可以使用命令:xcrun dwarfdump -–uuid <AppName.app/ExecutableName>

比如:

xcrun dwarfdump --uuid appName.app/appName

结果如下:

UUID: 8BDEAF1A-0B23-3AC1-9972-8C2A0EBB4165 (armv7) appName.app/appName

UUID: 5EA16BAC-BB52-3519-B218-342455A52E11 (armv7s) appName.app/appName

这个app有2个UUID,表明它是一个fat binnary。

它能利用最新硬件的特性,又能兼容老版本的设备。

对比上面crash文件和app文件的UUID,发现它们是匹配的

8BDEAF1A-0B23-3AC1-9972-8C2A0EBB4165

用atos命令来符号化某个特定模块加载地址

命令是:

atos [-o AppName.app/AppName] [-l loadAddress] [-arch architecture]

亲测:下面3种都可以:

  • xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -l 0x4000 -arch armv7

  • xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -arch armv7

  • xcrun atos -o appName.app/appName -arch armv7

(这3行选任意一行执行都可以达到目的,其中0x4000是模块的加载地址,从上面的章节可以找到如何得到这个地址。)

文章开头提到crash文件中有如下两行,

* 3 appName 0x000f462a 0x4000 + 984618 
* 4 appName **0x00352aee** 0x4000 + 3468014  

在执行了上面的

xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -l 0x4000 -arch armv7

之后,输入如下地址:

0x00352aee

(crash文件中的第4行:4 appName **0x00352aee** 0x4000 + 3468014

可以得到结果:

-[UIScrollView(UITouch) touchesEnded:withEvent:] (in appName) (UIScrollView+UITouch.h:26)

这样就找到了应用种到底是哪个模块导致的crash问题。


总结

本文分析了拿到用户的.crash文件之后,如何符合化crash文件的3种方法,分别有其适用场景,方法3适用于自动化crash文件的分析。


参见:

[1] :How to Match a Crash Report to a Build

[2] :Understanding and Analyzing iOS Application Crash Reports

[3] :Fixing Bugs: Using OS X crash logs and atos to symbolicate and find line numbers

[4] :Symbolicating Crash Logs

[5] :Symbolicating iPhone App Crash Reports


关于我

大家好,我是@吴发伟Ted,我会在博客上分享自己学习的一些东西。

好文推荐 && iOS Wiki

好文推荐(news.ios-wiki.com)iOS Wiki(www.ios-wiki.com)是我利用业余时间建立的网站。

欢迎使用Feedly等工具订阅好文推荐RSS Feed

微信公众账号

微信公众账号:iOS技术分享

目录
相关文章
|
14天前
|
安全 Android开发 数据安全/隐私保护
深入探讨iOS与Android系统安全性对比分析
在移动操作系统领域,iOS和Android无疑是两大巨头。本文从技术角度出发,对这两个系统的架构、安全机制以及用户隐私保护等方面进行了详细的比较分析。通过深入探讨,我们旨在揭示两个系统在安全性方面的差异,并为用户提供一些实用的安全建议。
|
2月前
|
开发工具 Android开发 Swift
安卓与iOS开发环境对比分析
在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统无疑是主角。它们各自拥有独特的特点和优势,为开发者提供了不同的开发环境和工具。本文将深入浅出地探讨安卓和iOS开发环境的主要差异,包括开发工具、编程语言、用户界面设计、性能优化以及市场覆盖等方面,旨在帮助初学者更好地理解两大平台的开发特点,并为他们选择合适的开发路径提供参考。通过比较分析,我们将揭示不同环境下的开发实践,以及如何根据项目需求和目标受众来选择最合适的开发平台。
51 2
|
3月前
|
语音技术 开发工具 图形学
Unity与IOS⭐一、百度语音IOS版Demo调试方法
Unity与IOS⭐一、百度语音IOS版Demo调试方法
|
11天前
|
监控 iOS开发 开发者
iOS性能优化:深入函数调用栈与符号化技术
在iOS开发中,函数调用栈是理解程序执行流程和优化性能的关键。当应用出现性能问题或崩溃时,能够准确地读取和解析调用栈信息对于快速定位问题至关重要。本文将探讨iOS中的函数调用栈,以及如何通过符号化技术进行有效的性能调优。
24 3
|
11天前
|
监控 算法 iOS开发
深入探索iOS函数调用栈:符号化与性能调优实战
在iOS开发中,理解函数调用栈对于性能调优和问题排查至关重要。函数调用栈记录了程序执行过程中的函数调用顺序,通过分析调用栈,我们可以识别性能瓶颈和潜在的代码问题。本文将分享iOS函数调用栈的基本概念、符号化过程以及如何利用调用栈进行性能调优。
31 2
|
2月前
|
安全 Android开发 数据安全/隐私保护
探索安卓与iOS的安全性差异:技术深度分析与实践建议
本文旨在深入探讨并比较Android和iOS两大移动操作系统在安全性方面的不同之处。通过详细的技术分析,揭示两者在架构设计、权限管理、应用生态及更新机制等方面的安全特性。同时,针对这些差异提出针对性的实践建议,旨在为开发者和用户提供增强移动设备安全性的参考。
136 3
|
1月前
|
开发工具 Android开发 Swift
安卓与iOS开发环境的差异性分析
【10月更文挑战第8天】 本文旨在探讨Android和iOS两大移动操作系统在开发环境上的不同,包括开发语言、工具、平台特性等方面。通过对这些差异性的分析,帮助开发者更好地理解两大平台,以便在项目开发中做出更合适的技术选择。
|
2月前
|
安全 Linux Android开发
探索安卓与iOS的安全性差异:技术深度分析
本文深入探讨了安卓(Android)和iOS两个主流操作系统平台在安全性方面的不同之处。通过比较它们在架构设计、系统更新机制、应用程序生态和隐私保护策略等方面的差异,揭示了每个平台独特的安全优势及潜在风险。此外,文章还讨论了用户在使用这些设备时可以采取的一些最佳实践,以增强个人数据的安全。
|
3月前
|
Java 开发工具 Android开发
安卓与iOS开发环境对比分析
【8月更文挑战第20天】在移动应用开发的广阔天地中,Android和iOS两大平台各自占据着重要的位置。本文将深入探讨这两种操作系统的开发环境,从编程语言到开发工具,从用户界面设计到性能优化,以及市场趋势对开发者选择的影响。我们旨在为读者提供一个全面的比较视角,帮助理解不同平台的优势与挑战,并为那些站在选择十字路口的开发者提供有价值的参考信息。
|
2月前
|
IDE 开发工具 Android开发
安卓与iOS开发环境对比分析
本文将探讨安卓和iOS这两大移动操作系统在开发环境上的差异,从工具、语言、框架到生态系统等多个角度进行比较。我们将深入了解各自的优势和劣势,并尝试为开发者提供一些实用的建议,以帮助他们根据自己的需求选择最适合的开发平台。
47 1