CrashLog处理

iOS Crash文件分析 一. iOS crashs 一般有如下四种: Application crash Low memory Watchdog timeout User force-quit 当前我们的 ERead 程序遇到了前三种 core 问题。只有 Application crash 文件才会提供有用的

iOS Crash文件分析

一.iOS crashs一般有如下四种:

Application crash
       Low memory
       Watchdog timeout
       User force-quit



当前我们的ERead程序遇到了前三种core问题。只有Application crash文件才会提供有用的crash堆栈。

Low memory 主要是程序申请不到可用的内存或者剩余内存不足以支持程序运行而产生的crash.


WatchDog timeout 是程序100%暂用cpu超过10s而产生的crash文件。
     User force-quit :暂时还没搞清什么情况下会出现。
二.如何找到crash文件 
a)
iPhone真机上Crash文件的存储路径为:/var/mobile/Library/Logs/CrashReporter
可以通过PhoneView(mac下),91助手(windows下)读取。
b)
需要保存***.app.dSYM 符号文件(生产版本的时候和***.app同在build目录)
c)
获取crash文件:

i.
可以直接连接到itunes,itunes会自动把crash文件同步到pc机,在pc上的目录是:~/Library/Logs/CrashReporter/MobileDevice下面。
同步完成后也可以在XCode的Window的Organizer下面,找到相应Device设备,选择DeviceLog标签,找到相应的crash文件。

 

 

 




三. crash文件介绍
⒈一般如果是内存过低引起的core问题,crash文件会命名为“LowMemory-2011-06-05-044757.log”的格式,其中的日期为同步到pc时的日期
2.如果是其他原因引起的core问题,crash文件会命名为“ETReader_2011-04-12-103850_adminmato-iPad.crash”的格式,其中日

期为同步到pc的时间,adminmato-iPad指的是当前所有设备所取的名称
一般情况下,我们只看第二种的crash文件,第一种crash文件是和手机内存大小及程序占用内存有关,一般情况下不做处理


四.通过crash文件定位问题(针对Application crash,其他crash文件无法提供有效信息)
把***.app.dSYM和crash文件放到同一个目录下

 

执行命令:symbolicatecrash ***.crash ***.app.dSYM | less

 

就 会得到符号化好的crash文件。如果crash是通过itunes同步到pc机,并且在Organizer中查看的话,那么看到的crash是已经由 xcode调用symbolicatecrash 命令符号化好了的(右键Reveal Log in Finder可以得到该crash文件)。

crash例子文件如下:
Incident Identifier: 2664D48C-C1D7-43EC-8E89-01D27EE2E7E0

CrashReporter Key:
ae8ae7a933bd6670313190b38a0b7a9cd6fb5329
Hardware Model:
iPhone2,1
Process:     ETReader [3445]
Path:
/var/mobile/Applications/C7C76450-4A8D-4CFE-B662-923523CFADB1/ETReader.app/ETReader
Identifier:    ETReader
Version:
??? (???)
Code Type:  ARM (Native)
Parent Process:  punchd [1]

Date/Time:   2011-04-14 15:21:24.064 +0800
OS Version:  iPhone OS 4.2.1 (8C148a)
Report Version:  104



Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000004
Crashed Thread: 0

Thread 0 Crashed:
0  ETReader                0x0009dcc8 0x1000 + 642248
1  ETReader                0x0003baf2 0x1000 + 240370
2   Foundation             0x31cd861c 0x31cc4000 + 83484
3   CoreFoundation     0x3145711c 0x31430000 + 160028
4   CoreFoundation      0x31456dbc 0x31430000 + 159164
5   Foundation              0x31cc7d1c 0x31cc4000 + 15644
6   Foundation              0x31cd123a 0x31cc4000 + 53818
7   UIKit                         0x338ff904 0x3389e000 + 399620
8   UIKit                         0x338fdbb8 0x3389e000 + 392120
9   UIKit                         0x338a27a6 0x3389e000 + 18342

Binary Images:

0x1000 -
0xd2fff +ETReader armv7
<e2cd3c3a2d5d5cecc3ceec0792b50309> /var/mobile/Applications/C7C76450-4A8D-4CFE-B662-923523CFADB1/ETReader.app/ETReader

0x1f5000 -
0x1f5fff +MobileSubstrate.dylib armv6
<93c7cc820225e9453a9f93d3b21a25fa> /Library/MobileSubstrate/MobileSubstrate.dylib

0x225000 -
0x226fff +SubstrateLoader.dylib armv6
<073e8f5afee21e96e513e796622bfd6f> /Library/Frameworks/CydiaSubstrate.framework/Libraries/SubstrateLoader.dylib

0x22a000 -
0x22bfff
dns.so armv7
<fcefecb2d5e095ba88127eec3af57ec0> /usr/lib/info/dns.so

0x246000 -
0x258fff +SBPandaHome.dylib armv6
<8bfff4a460e806aca029a0b989419225> /Library/MobileSubstrate/DynamicLibraries/SBPandaHome.dylib

0x264000 -
0x267fff
libsubstrate.dylib armv6
<9ad52a9dd3b8e54ae1b0a0e5fc58c7a2> /usr/lib/libsubstrate.dylib

发现有针对ETReader的堆栈地址:
0   ETReader                      0x0009dcc8 0x1000 + 642248

1   ETReader                      0x0003baf2 0x1000 + 240370
但是如何把地址映射到相应的文件对应的函数呢。
需要在命令行执行如下命令:

dwarftdump –lookup 0x0009dcc8
–arch
armv7 
***.app.dSYM
此处到底是armv7还是armv6,在 Binary Images附近可以查看体系结构(红色大字体标注)。

执行完该命令会在控制台上打印出一堆定位信息,好啦后面我就不啰嗦了,可以自己分析啦。

 

Bug是永远伴随着程序员们的东西,各种各样的情况造成程序crash掉也是家常便饭。Windows下的很多大型软件在崩溃的时候,都会弹出提示 框,询问用户是否将crash的信息发送到软件厂商,以供软件开发商debug。App store中的软件也有这个功能,用户在使用软件的时候,如果程序崩溃,错误信息会发送到Apple的服务器中,软件的开发者们可以很方便在后台获得自己 程序的crash log,供自己调试。

但随之而来的问题是,我们收到的程序崩溃调试信息多半是汇编语言一样的堆栈代码,同时这些信息并不 是在我们debug的时候产生,所以看到这一串crash log的天书,常常无可奈何。Xcode很好的解决了这一问题,它所提供的Orgainzer分析器加上symbolicatecrash,可以分析二 进制文件以及源代码和crashlog之间的连接,直接找出源程序中出错的代码行。方法网上到处是,本文不讨论。

但是如果使用symbolicatecrash无法定位到出错的代码行的话,怎么整呢?有一个办法,如下:

首先查看crash log中的崩溃线程,假如是这样的:

Thread 0 Crashed:
0   libobjc.A.dylib               0x00003ec0 objc_msgSend + 24
1   MyApp               0x000036d2 0×1000 + 9938

我们得到了用户发生崩溃情况的内存地址:0x000036d2

然后回到我们应用程序的build目录,目录下一定要包含MyApp.app 和MyApp.app.dSYM两个文件。

在控制台使用dwarfdump命令,解析出内存地址,如: 

dwarfdump –lookup 0x000036d2 –arch armv6 MyApp.app.dSYM

输出信息如下:

直接定位到代码的出错行,Cool!

posted on 2012-06-12 10:14  甲骨魚  阅读(1569)  评论(0编辑  收藏  举报

导航