一、获取Crash Log的方式

在iOS开发过程,当应用已经打包,iPhone设备通过ipa的包安装应用后,在使用过程发现crash,那么如何获取crash日志呢,现提供如下四种获取crash日志的方式:

1、打开iPhone设备的设置里面的隐私中的“诊断与用量”,然后如果app崩溃了,设备会弹出提示框,用户确认之后,crash log会自动发送到苹果后台,然后用开发者账号登陆上去,可以拿到crash log。

2、将设备链接到mac或者windows上,同步到iTunes后再从电脑的目录下获取crash log:

Mac OS X:~/Library/Logs/CrashReporter/MobileDevice

Windows XP:C:\Documents and Settings\Application Data\Apple computer\Logs\CrashReporter

Windows 7/Vista: C:\Users\计算机登录名\AppData\Roaming\Apple Computer\Logs\CrashReporter\MobileDevice

3、可以通过itools工具获取crash log,打开itools,连接iPhone设备,按照下图提示,获取crash log

4、通过xcode获取crash log,打开Xcode,连接iPhone设备,打开window下的device,可以看到你连接的设备,可以看到如下界面,点击view device logs,可以看到所有的日志,选中日志,点击右键可以到处日志

二、解析Crash Logs --- 符号化crash文件(Symbolicating crash logs)

crash logs:

 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个文件:

  1. crash报告(.crash文件)
  2. 符号文件 (.dsymb文件)
  3. 应用程序文件 (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

1.UUID

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

2.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的时候会用到)

3.找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类型

1、Watchdog timeout

Exception Code:0x8badf00d, 不太直观,可以读成“eat bad food”,意思是don‘t block main thread

紧接着下面会有一段描述:

Application Specific Information:

com.xxx.yyy   failed to resume in time

对于此类Crash,我们应该去审视自己App初始化时做的事情是否正确,是否在主线程请求了网络,或者其他耗时的事情卡住了正常初始化流程。

通常系统允许一个App从启动到可以相应用户事件的时间最多为5S,如果超过了5S,App就会被系统终止掉。在Launch,resume,suspend,quit时都会有相应的时间要求。在Highlight Thread里面我们可以看到被终止时调用到的位置,xxxAppDelegate加上行号。

PS. 在连接Xcode调试时为了便于调试,系统会暂时禁用掉Watchdog,所以此类问题的发现需要使用正常的启动模式。

2、User force-quit

Exception Codes: 0xdeadfa11, deadfall

这个强制退出跟我们平时所说的kill掉后台任务操作还不太一样,通常在程序bug造成系统无法响应时可以采用长按电源键,当屏幕出现关机确认画面时按下Home键即可关闭当前程序。

3、Low Memory termination

跟一般的Crash结构不太一样,通常有Free pages,Wired Pages,Purgeable pages,largest process 组成,同事会列出当前时刻系统运行所有进程的信息。

关于Memory warning可以参看我之前写的一篇文章IOS 内存警告 Memory warning level。

App在运行过程中,系统内存紧张时通常会先发警告,同时把后台挂起的程序终止掉,最终如果还是内存不够的话就会终止掉当前前台的进程。

当接受到内存警告的事后,我们应该释放尽可能多的内存,Crash其实也可以看做是对App的一种保护。

4、Crash due to bugs

因为程序bug导致的Crash通常千奇百怪,很难一概而论。大部分情况通过Crash日志就可以定位出问题,当然也不排除部分疑难杂症看半天都不值问题出在哪儿。这个就只能看功底了,一点点找,总是能发现蛛丝马迹。是在看不出来时还可以求助于Google大神,总有人遇到和你一样的Bug

五、常见的Exception Type

1. EXC_BAD_ACCESS

此类型的Excpetion是我们最长碰到的Crash,通常用于访问了不改访问的内存导致。一般EXC_BAD_ACCESS后面的"()"还会带有补充信息。

SIGSEGV: 通常由于重复释放对象导致,这种类型在切换了ARC以后应该已经很少见到了。

SIGABRT: 收到Abort信号退出,通常Foundation库中的容器为了保护状态正常会做一些检测,例如插入nil到数组中等会遇到此类错误。

SEGV:(Segmentation Violation),代表无效内存地址,比如空指针,未初始化指针,栈溢出等;

SIGBUS:总线错误,与 SIGSEGV 不同的是,SIGSEGV 访问的是无效地址,而 SIGBUS 访问的是有效地址,但总线访问异常(如地址对齐问题)

SIGILL:尝试执行非法的指令,可能不被识别或者没有权限

2. EXC_BAD_INSTRUCTION

此类异常通常由于线程执行非法指令导致

3. EXC_ARITHMETIC

除零错误会抛出此类异常

六、我在“牛牛好管家”项目中遇到的Crash Log做以下分析

项目在模拟器上一直没有问题,可是到真机上突然发生了Crash,瞬间整个人都感觉不好了。导出了机子上的Crash报告,咋一看天书一般,经过在http://stackoverflow.com上面查找终于搞明白了原因。先附上Crash报告:

// 1: Process Information
Incident Identifier: CCBEE2BC-E2FB-4E43-83D5-FBD6B87F2ADE
CrashReporter Key:   703cffef5d700f1eaa0d3921fb8ef142d4780cf9
Hardware Model:      iPhone8,1
Process:             NiuNiu [5639]
Path:                /private/var/mobile/Containers/Bundle/Application/A37341B1-FC88-4E49-A102-017A7AE5218C/NiuNiu.app/NiuNiu
Identifier:          com.sdbean.NiuNiuManagers
Version:             2.9.1 (1.3)
Code Type:           ARM-64 (Native)
Parent Process:      launchd [1]// 2: Basic Information
Date/Time:           2016-03-21 08:30:02.02 +0800
Launch Time:         2016-03-19 07:54:25.25 +0800
OS Version:          iOS 9.2.1 (13D15)
Report Version:      105// 3: Exception
Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Triggered by Thread:  0Filtered syslog:
None foundLast Exception Backtrace:
(0x181375900 0x1809e3f80 0x1812641a8 0x181264040 0x1000d0dc0 0x1000d07f0 0x180dc9630 0x180dc95f0 0x180dcecf8 0x18132cbb0 0x18132aa18 0x181259680 0x182768088 0x1860d0d90 0x1000ec1b0 0x180dfa8b8)Global Trace Buffer (reverse chronological seconds):
1.273655     CFNetwork                  0x00000001819ef104 TCP Conn 0x126ca8d20 complete. fd: 8, err: 0// 4: Threads backtraces
Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libsystem_kernel.dylib          0x0000000180f18140 0x180efc000 + 115008
1   libsystem_pthread.dylib         0x0000000180fe0ef8 0x180fdc000 + 20216
2   libsystem_c.dylib               0x0000000180e89dac 0x180e28000 + 400812Thread 1 name:  Dispatch queue: com.apple.libdispatch-manager
Thread 1:
0   libsystem_kernel.dylib          0x0000000180f194fc 0x180efc000 + 120060
1   libdispatch.dylib               0x0000000180ddc94c 0x180dc8000 + 84300
2   libdispatch.dylib               0x0000000180dcb7bc 0x180dc8000 + 14268// 此处省略// 5: Thread state
Thread 0 crashed with ARM Thread State (64-bit):x0: 0x0000000000000000   x1: 0x0000000000000000   x2: 0x0000000000000000   x3: 0x00000001256111a1x4: 0x00000001809daba2   x5: 0x000000016fd95940   x6: 0x000000000000006e   x7: 0x00000000000000e0// 6: Binary images
Binary Images:
0x100068000 - 0x1001fbfff NiuNiu arm64  <136fc60898023e57934bf98a2da74a2e> /var/mobile/Containers/Bundle/Application/A37341B1-FC88-4E49-A102-017A7AE5218C/NiuNiu.app/NiuNiu
0x120020000 - 0x12004ffff dyld arm64  <9e98992ceed735e2ac4784cb28efe7c1> /usr/lib/dyld
0x180964000 - 0x180965fff libSystem.B.dylib arm64  <c4cd04b37e5f34698856a9384aefff40> /usr/lib/libSystem.B.dylib
0x180968000 - 0x1809bbfff libc++.1.dylib arm64  <d430d0ad16893b76bbc52468f65d5906> /usr/lib/libc++.1.dylib
0x1809bc000 - 0x1809dbfff libc++abi.dylib arm64

现在做一下分析:

(1)Process Information

    这部分给出了进程crash后的部分信息

Incident Identifier crash报告的唯一标识
CrashReporter Key crash报告映射到Device Identifier的唯一键值(key)。表面上看上去没有任何含义,但实际上给我们提供了一个有用信息,假如我们所获得的大量crash log拥有同样的Crashreport Key,一定程度上说明这个crash问题并不是普遍存在,也许只是对一些特定的设备存在。
Hardware Model 当前设备类型。假如我们所获得的大量crash log拥有同样的Hardware Model,很大程度上可以说明app在该类设备上运行存在适配的问题。
Process app的名字。
(2)Basic Information

这部分给出了crash的一些基本信息:crash发生的时间,当前设备上操作系统的版本等。如果多数crash log拥有相同的iOS版本号,一定程度上说明app对于该版本iOS系统存在适配问题。

(3)Exception

这部分给出了crash的异常类型,异常错误码和抛出异常的线程。

(4)Threads backtraces

这部分给出了crash时app所有线程的堆栈记录,列出crash时函数调用堆栈。

(5)Thread state

这部分给出了crash时寄存器中的值。事实上,堆栈记录已经提供了类似的信息。

(6)Binary images

这部分列出了crahs时加载的所有文件。

接下来,我们在看一个内存警告的crash log

可以看到,第一部分和之前的crash log内容类似,这里对其他部分的含义作简要的说明:

Free pages 代表可用内存,每个page近似为4KB,故,上面的log里面显示的可用内存为3,872 KB (or 3.9 MB)
Purgeable pages 代表可清除和重用的内存,上面的log显示为0KB
Largest process crash时占用内存最多的应用
Processes 列出进程列表及crash时进程的内存占用情况,包含进程名字,进程唯一标识符,进程使用的page数,app状态(一般情况下引起crash的app拥有frontmost状态)
附录:
这里有一些比较常见的异常码:

1)0x8badf00d  记作“ate bad food”,这个异常一般是因为系统监视器发现超时现象,比如启动或终止超时,亦或者是长时间响应系统时间(event)。
2)0xbad22222  标志VoIP类应用因为频繁启动被终止。
3)0xdead10cc  记作“dead lock”,当应用在后台运行时,由于占用(hold onto)系统资源(比如通讯录数据库),被操作系统终止。
4)0xdeadfa11  记作“deadfall”,标志应用程序可能因为无响应被用户强行终止。

转载于:https://www.cnblogs.com/CoderLiLe/p/5359491.html

iPhone真机测试Crash信息分析相关推荐

  1. iphone固件升级到3.1.3 ,HelloWorld成功安装到iPhone真机测试

    2010-07-04 iphone固件升级到3.1.3 , XCode iPhone SDK 3.1.3 HelloWorld成功安装到iPhone真机测试

  2. ionic应用在mac上使用Xcode7.2(7C68)进行iphone真机测试

    1.前提环境 : 假设已经在mac(OS X El Capitan 版本 10.11.2)上装好了Xcode7.2(7C68)和ionic环境 2.运行添加ios平台命令 ionic platform ...

  3. Xcode如何实现iphone真机测试

    1.点击左上角菜单Xcode -> Preferences. 2.在跳出来的小窗口页面的左下角,点击加号添加苹果id. 3.在账号密码输入完毕后,点击小窗口右下角的view details或者双 ...

  4. cocos2d-x iphone真机测试出现闪屏现象

    最近在学着写一个跑酷游戏.使用cocos2d-x , ios平台. 在真机测试时候,发现出现闪屏现象,如图所示. 后来发现了2个解决方法,mark一下. // 解决方法 A:关闭深度检测 CCDire ...

  5. iOS: iphone在真机测试以及apns的设置

    以开发一个"MobileCAP" app为例 Step 1: Create cert request file.(当你在apple web site "provision ...

  6. iphone 4 程序开发:真机测试 (免费无99刀)

    要给iphone开发程序,我们需要一个mac系统(我是用pc机装的lion10.7),以及xcode(我用的是xcode4.1和ios4.3sdk),当然,你还需要一台iphone来进行真机测试. 当 ...

  7. iOS 三方登录 微信登录失败 真机测试 由于应用BundleID信息校验不通过,无法使用微信登录

    真机测试 打包到蒲公英 一切顺利 但是在测试同胞那里 微信的三方登录失败 报错原因如下 解决办法 在微信开放平台将这个项目的bundle ID改成和打包项目中的一致即可

  8. Unity导出到AS中真机测试apk没有问题,aab提交到GooglePlay审核通过,但是从Google Play下载的应用闪退问题

    兄弟们,姐妹们,历尽两个月,改得我都怀疑自己适不适合搞这行了!!!真的是把网上说得可能得问题和解决方法都尝试了一遍,快疯了!! 看google开发者后台得测试报告,提供得crash信息: signal ...

  9. Sonic 开源移动端云真机测试平台 - windows系统下的sonic快速部署演示

    Sonic 开源移动端云真机测试平台快速部署演示 第一章:Sonic 平台的准备工作与快速部署 ① Docker 的安装 ② MySQL 的安装 ③ docker-compose.yml 文件配置 ④ ...

  10. Xcode 真机测试破解方法(转加修改)xcode 4.3 通过

    Xcode 真机测试破解方法(转加修改)xcode 4.3 通过 生成本机证书 应用程序->实用工具->钥匙串访问 菜单:钥匙串访问->证书助理->创建证书, 然后按以下图片顺 ...

最新文章

  1. SpringCloud Alibaba微服务实战(六) - 路由网关(Gateway)
  2. 第二部分:S5PV210_关看门狗_1
  3. Oracle 解决4031错误
  4. wxWidgets:国际化
  5. ffmpeg 时间戳
  6. Flutter 使用Android Studio 创建第一个应用
  7. MySQL 5.7 忘记密码
  8. python使用-python使用
  9. 不同域名指向静态图片文件
  10. 喝酒必备神器微信小程序源码下载免服务器和域名带流量主收益
  11. python 快乐的数字
  12. 后台api接口幂等防止数据篡改,看完发现心领神会
  13. Win32反汇编(三)深层次的了解各种转移指令:IF语句有符号与无符号跳转
  14. 计算机社团活动展望未来,社团展望未来演讲稿(2)
  15. 常见的开发模式和不常见的开发模式
  16. mysq学习课堂笔记 第一天学习(值得收藏!)
  17. 区块链Fabric 技术架构和交易流程
  18. Linux内核配置选项的说明,Linux内核配置选项翻译
  19. 微信小程序点击复制功能
  20. 智能电表市场容量分析,年出货破亿颗

热门文章

  1. 挑筋(挑治)疗法——针挑治疗痔疮
  2. 微信如何推送html文件,微信推送怎么附上文件_怎样在微信公众号上传附件图文步骤...
  3. 推荐股票理财博客-徐小明
  4. pxhere - 世界知名的免费摄影图库,可以免费商用
  5. 特征工程之特征选择(4)----嵌入法(Embed)
  6. TomCat8080/8081端口占用问题!如何解决
  7. c语言求范围内最大素数,for语句计算输出10000以内最大素数怎么搞最简单??各位大神们...
  8. 学生用计算机指数函数,指数函数计算器
  9. 怎么在档案写自己的计算机水平,关于个人档案怎么写范文
  10. 计算机网络模拟器 mac,网易mumu模拟器mac版使用常见问题解决办法_3DM手游