获取设备上的调试信息与崩溃日志分析

做开发的过程中,调试时遇到什么bug,首先就是要定位bug在哪。此时,如果可以重现这个bug,能把设备接到电脑上调试是最好不过了。

但是,但是能重现的bug一般一眼就能看出来是什么问题好么。最头疼的是,给测试设备上安装了app,然后去给策划或测试试玩,结果他们说程序闪退,但又不能重现出来。。。

现在有办法解决这个问题了。需要如下三个步骤即可:

1.取出或者查看设备上的崩溃日志。

2.分析崩溃日志,找到报错在哪里(定位到函数和代码行数)。

3.打开代码,改bug咯。


先从ios设备来看吧。这里引用一篇近乎完美的博客: iOS应用崩溃日志分析(感谢博主)文章中详细的讲了ios设备查看崩溃日志的过程,以及常见的问题。


总结起来,有三种方式可以查看到ios设备上的崩溃日志。

1.在可以获取到运行app的手机,或者用户配合导出日志的情况下。可以将设备连接到电脑,然后与电脑上的iTunes同步,崩溃日志会同步到电脑上的指定文件夹。(上面博客有指明)

2.在可以直接获取到运行app的手机的情况下。可以将设备连接到电脑,然后打开xcode软件,选择Window->Devices,然后可以在xcode中查看设备上的所有崩溃日志。

3.在app已经上线的情况下,可以通过iTunes Connect获取用户的崩溃日志。


获取崩溃日志之后,就可以进入第二步,日志分析了。这边我也拿一段崩溃日志来分析一下。

//崩溃日志基本信息
Incident Identifier: 6F309552-C289-42F2-B6BB-E54AFCF533C8
CrashReporter Key:   df911cdd677cc29c3aa0ee4b050148d32de03fce
Hardware Model:      iPad2,5
Process:             MyApp-mobile [36063]
Path:                /private/var/mobile/Containers/Bundle/Application/8F7E2D1B-E882-476C-A8D7-D1B47C6C66B5/MyApp-mobile.app/MyApp-mobile
Identifier:          com.qfl.MyApp
Version:             1.0 (1.0.0)
Code Type:           ARM (Native)
Parent Process:      launchd [1]
//崩溃时间和系统版本号
Date/Time:           2016-04-06 15:11:24.24 +0800
Launch Time:         2016-04-06 15:11:16.16 +0800
OS Version:          iOS 9.0.2 (13A452)
Report Version:      104
//导致崩溃的异常
Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x00000050
Triggered by Thread:  0

Filtered syslog:
None found
//线程回溯
Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   ???                           	0x00000050 0 + 80
1   MyApp-mobile      	0x000bb800 0x4000 + 751616
2   MyApp-mobile      	0x004052fc 0x4000 + 4199164
3   MyApp-mobile      	0x00509bdc 0x4000 + 5266396
4   MyApp-mobile      	0x00509e7c 0x4000 + 5267068
5   MyApp-mobile      	            0x00507126 0x4000 + 5255462
6   MyApp-mobile      	0x00508d24 0x4000 + 5262628
7   MyApp-mobile      	0x00508b68 0x4000 + 5262184
8   MyApp-mobile      	0x005948d6 0x4000 + 5834966
9   MyApp-mobile      	0x00587792 0x4000 + 5781394
10  MyApp-mobile      	0x005873a6 0x4000 + 5780390
11  MyApp-mobile      	0x00587310 0x4000 + 5780240
12  MyApp-mobile      	0x0058b00a 0x4000 + 5795850
13  MyApp-mobile      	0x00581438 0x4000 + 5755960
14  MyApp-mobile      	0x00581f5a 0x4000 + 5758810
15  MyApp-mobile      	0x00581680 0x4000 + 5756544
16  MyApp-mobile      	0x005c10fc 0x4000 + 6017276
17  MyApp-mobile      	0x005c1296 0x4000 + 6017686
18  MyApp-mobile      	0x0059fa98 0x4000 + 5880472
19  UIKit               0x29558cfe -[UIWindow _sendTouchesForEvent:] + 646
20  UIKit               0x29551e56 -[UIWindow sendEvent:] + 642
21  UIKit               0x295237e4 -[UIApplication sendEvent:] + 204
22  UIKit               0x29521fde _UIApplicationHandleEventQueue + 4934
23  CoreFoundation      0x25422c3e __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
24  CoreFoundation      0x2542282c __CFRunLoopDoSources0 + 452
25  CoreFoundation      0x25420b9a __CFRunLoopRun + 794
26  CoreFoundation      0x25374248 CFRunLoopRunSpecific + 520
27  CoreFoundation      0x25374034 CFRunLoopRunInMode + 108
28  GraphicsServices    0x2e42bad0 GSEventRunModal + 160
29  UIKit               0x29589898 UIApplicationMain + 144
30  MyApp-mobile      	0x000e6556 0x4000 + 927062
31  libdyld.dylib       0x37412872 start + 2

Thread 1:
0   libsystem_kernel.dylib        	0x374e292c __workq_kernreturn + 8
1   libsystem_pthread.dylib       	0x37582b50 _pthread_wqthread + 1036
2   libsystem_pthread.dylib       	0x37582734 start_wqthread + 8

Thread 2 name:  Dispatch queue: com.apple.libdispatch-manager
Thread 2:
0   libsystem_kernel.dylib        	0x374e33c0 kevent_qos + 24
1   libdispatch.dylib             	0x373dd1c8 _dispatch_mgr_invoke + 256
2   libdispatch.dylib             	0x373dcf26 _dispatch_mgr_thread$VARIANT$mp + 38
//线程回溯最后面还有二进制信息
Binary Images:

虽然崩溃日志是看到了,通过异常信息也能知道是什么原因。但是并不能定位到我们自己的代码啊。

上面可以看到,关于我们自己的代码  MyApp开头的行,我们只能看到一些符号。并没有指定到某个函数,某一行。其实,这个崩溃日志是没有经过符号化的,所以我看不懂。

这里符号化是有两种方式的:

1.在xcode中查看崩溃日志,xcode会自动将日志符号化。

2.通过终端命令,手动符号化。


这两种方式都需要dSYM文件。这里需要查看一下项目的Build Settigns->Build Options->Debug information Format属性。只有该属性设置为DWARF with dSYM File时,编译才会生成dSYM文件。如果忘了设置,就重新设置一下,然后重新编译工程(Clean然后再Build)即可。dSYM文件和app包是对应的,如果不对应,可能无法符号化日志,所以切记在打包app提交测试时,要保存对应版本的dSYM文件。

如果已经设置好了可以在

/Users/qfl/Library/Developer/Xcode/DerivedData/MyApp-aerllxbslxqnjhgfeoiagutyemyz/Build/Products/Debug-iphoneos

目录下找到app和dSYM文件。


如果在xcode中查看崩溃日志,xcode会自动将日志符号化。所以这里只看第二种方式了,使用atos命令来符号化崩溃日志。

格式如下: 

atos -o dysm 文件路径 -l 模块load地址(后面的一个16进制地址) -arch cpu指令集 调用方法的地址(前面一个16进制地址)

大家可以从这里看示例:iOS Crash 分析(文三)- 符号化崩溃日志 (感谢博主)


现在直接可以看到符号化后的内容,就可以到自己的代码中找到报错的地方了。


这边还有一个需要注意的地方。

例子1:

Date/Time:           2016-04-06 15:02:22.22 +0800
Launch Time:         2016-04-06 15:02:17.17 +0800
OS Version:          iOS 9.0.2 (13A452)
Report Version:      104

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x00000050
Triggered by Thread:  0

Filtered syslog:
None found

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   ???                           	0x00000050 0 + 80
1   MyApp-mobile      	0x00102800 std::__1::__function::__func, void (cocos2d::Ref*)>::operator()(cocos2d::Ref*&&) (functional:1437)
2   MyApp-mobile      	0x0044c2fc std::__1::function::operator()(cocos2d::Ref*) const (functional:1817)
3   MyApp-mobile      	0x00550bdc cocos2d::MenuItem::activate() (CCMenuItem.cpp:105)
4   MyApp-mobile      	0x00550e7c cocos2d::MenuItemLabel::activate() (CCMenuItem.cpp:241)
5   MyApp-mobile      	0x0054e126 cocos2d::Menu::onTouchEnded(cocos2d::Touch*, cocos2d::Event*) (CCMenu.cpp:290)
6 
从上面的信息看,指明了是MYTest类中的addUI()方法中报错了,但是没有指定到行。

我们可以从$_52看出,这里表示是第52个(从0开始)表达式中报错。

这个是我写的测试类,总共有52个表达式(一个屏蔽触摸,一个关闭测试页面,然后前面还有50个测试按钮。。。所以从0开始算,这里刚好是第52个表达式)

这是一个比较奇特的情况,一般写在函数中报错时,会看到很正常的某个函数(第n行)的报错。所以这里要注意一下。




你可能感兴趣的:(日志-必须每天一篇啊)