做开发的过程中,调试时遇到什么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 <span style="font-family: Arial, Helvetica, sans-serif;">MyA</span><span style="font-family: Arial, Helvetica, sans-serif;">pp</span><span style="font-family: Arial, Helvetica, sans-serif;">-mobile 0x00507126 0x4000 + 5255462</span> [plain] view plain copy
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
虽然崩溃日志是看到了,通过异常信息也能知道是什么原因。但是并不能定位到我们自己的代码啊。
上面可以看到,关于我们自己的代码 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命令来符号化崩溃日志。
格式如下:
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 <span style="font-family: Arial, Helvetica, sans-serif;">MyA</span><span style="font-family: Arial, Helvetica, sans-serif;">pp</span><span style="font-family: Arial, Helvetica, sans-serif;">-mobile 0x00507126 0x4000 + 5255462</span>
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<MYTest::addUI()::$_52, std::__1::allocator<MYTest::addUI()::$_52>, void (cocos2d::Ref*)>::operator()(cocos2d::Ref*&&) (functional:1437) 2 MyApp-mobile 0x0044c2fc std::__1::function<void (cocos2d::Ref*)>::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开始)表达式中报错。
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 <span style="font-family: Arial, Helvetica, sans-serif;">MyA</span><span style="font-family: Arial, Helvetica, sans-serif;">pp</span><span style="font-family: Arial, Helvetica, sans-serif;">-mobile 0x00507126 0x4000 + 5255462</span>