工程上线后,总会有几个崩溃,有的是操作问题,有的是程序bug,下面就是如何通过崩溃日志找到程序bug的过程
-
先弄到设备上APP的crash日志
参照(这篇日志),我的日志是从报错平台上得到的,这步跳过 -
打开报错日志(这里只保留了有用信息,不过你拿得到报错机器的话…直接看8.)
1234567891011121314Hardware Model: iPhone3,3 //设备型号Process: app [212] //进程名Identifier: com.company.bundleid //Bundle IDVersion: 1.3.13 //APP版本OS Version: iPhone OS 7.0 (11A465) //iOS版本Exception Type: SIGSEGV //错误类型Crashed Thread: 0 //Crash线程//线程0的堆栈Thread 0 Crashed:0 app 0x00145e90 0x2e000 11465121 app 0x00095095 0x2e000 422037 -
分析
gcld开头的应该就是引起崩溃的地方,不过完全看不懂
a) 创建一个crash文件夹
b) 把报错日志重命名成app.crash 放进crash文件夹
c) 问开发要xcarchive,从xcarchive里找到app.app和app.app.dSYM 放进crash文件夹
d) 复制/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash 放进crash文件夹
e) 打开Terminal
1234export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer./symbolicatecrash app.crash app.app.dSYM > app-symbol.crash
f) 我们看到了"got symbolicator for /Users/superyyl/Desktop/crash/app.app/app, base address 4000"这种日志 -
打开gcld-kuaiyong-symbol.crash文件
发现Thread 0的地方已经变样子了
12345Thread 0 Crashed:0 gcld 0x00145e90 ___lldb_unnamed_function6269$$gcld + 01 gcld 0x00095095 tolua_Cocos2d_CCSprite_setDisplayFrame00(lua_State*) (LuaCocos2d.cpp:21969) -
找到C代码
打开LuaCocos2d.cpp,找到21969行,看到C代码
123self->setDisplayFrame(pNewFrame); -
根据日志判断崩溃原因
错误类型是SIGSEGV,从signal.h文件中得知
12#define SIGSEGV 11 /* segmentation violation */</code>segmentation violation 内存段异常 pNewFrame为空了 -
分析用户的行为日志
such as:最近收发的数据包,最近调用的接口,进入的场景名
来跟踪lua代码可能出错的地方 -
既然拿得到设备…
a) 找开发要到当时版本的xcarchive,导入到xcode中
b) 连接设备
c) 从xcode里的Organizer-Devices里找到Device Logs
d) 找到崩溃的日志,左键单击
e) 开始的2秒,崩溃日志还是内存地址,但是2秒解析过后,就能找到具体行了 -
最后
这个方法能找到大部分的报错原因,但有时候拿到crash并非完全有效,比如你可能拿到大量例子中的"___lldb_unnamed_function6269"就无从下手
附录1:
Apple Hardware Model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
AppleTV(2G) (AppleTV2,1) AppleTV3,1 (AppleTV3,1) AppleTV3,2 (AppleTV3,2) iPad (iPad1,1) iPad2(wifi) (iPad2,1) iPad2(at&t) (iPad2,2) iPad2(vz) (iPad2,3) iPad2,4 (iPad2,4) iPad2,5 (iPad2,5) iPad2,6 (iPad2,6) iPad2,7 (iPad2,7) iPad3,1 (iPad3,1) iPad3,2 (iPad3,2) iPad3,3 (iPad3,3) iPad3,4 (iPad3,4) iPad3,5 (iPad3,5) iPad3,6 (iPad3,6) iPad4,1 (iPad4,1) iPad4,2 (iPad4,2) iPad4,4 (iPad4,4) iPad4,5 (iPad4,5) iPhone (iPhone1,1) iPhone3G (iPhone1,2) iPhone3GS (iPhone2,1) iPhone4 (iPhone3,1) iPhone3,2 (iPhone3,2) iPhone4(vz) (iPhone3,3) iPhone4S (iPhone4,1) iPhone5,1 (iPhone5,1) iPhone5,2 (iPhone5,2) iPhone5,3 (iPhone5,3) iPhone5,4 (iPhone5,4) iPhone6,1 (iPhone6,1) iPhone6,2 (iPhone6,2) iPodTouch(2G) (iPod2,1) iPodTouch(3G) (iPod3,1) iPodTouch(4G) (iPod4,1) iPodTouch(5G) (iPod5,1) |
附录2:
signal.h defines
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
#define SIGHUP 1 /* hangup */ #define SIGINT 2 /* interrupt */ #define SIGQUIT 3 /* quit */ #define SIGILL 4 /* illegal instruction (not reset when caught) */ #define SIGTRAP 5 /* trace trap (not reset when caught) */ #define SIGABRT 6 /* abort() */ #if (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE)) #define SIGPOLL 7 /* pollable event ([XSR] generated, not supported) */ #else /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ #define SIGIOT SIGABRT /* compatibility */ #define SIGEMT 7 /* EMT instruction */ #endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ #define SIGFPE 8 /* floating point exception */ #define SIGKILL 9 /* kill (cannot be caught or ignored) */ #define SIGBUS 10 /* bus error */ #define SIGSEGV 11 /* segmentation violation */ #define SIGSYS 12 /* bad argument to system call */ #define SIGPIPE 13 /* write on a pipe with no one to read it */ #define SIGALRM 14 /* alarm clock */ #define SIGTERM 15 /* software termination signal from kill */ #define SIGURG 16 /* urgent condition on IO channel */ #define SIGSTOP 17 /* sendable stop signal not from tty */ #define SIGTSTP 18 /* stop signal from tty */ #define SIGCONT 19 /* continue a stopped process */ #define SIGCHLD 20 /* to parent on child stop or exit */ #define SIGTTIN 21 /* to readers pgrp upon background tty read */ #define SIGTTOU 22 /* like TTIN for output if (tp->t_local<OSTOP) */ #if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) #define SIGIO 23 /* input/output possible signal */ #endif #define SIGXCPU 24 /* exceeded CPU time limit */ #define SIGXFSZ 25 /* exceeded file size limit */ #define SIGVTALRM 26 /* virtual time alarm */ #define SIGPROF 27 /* profiling time alarm */ #if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) #define SIGWINCH 28 /* window size changes */ #define SIGINFO 29 /* information request */ #endif #define SIGUSR1 30 /* user defined signal 1 */ #define SIGUSR2 31 /* user defined signal 2 */ #if defined(_ANSI_SOURCE) || __DARWIN_UNIX03 || defined(__cplusplus) /* * Language spec sez we must list exactly one parameter, even though we * actually supply three. Ugh! * SIG_HOLD is chosen to avoid KERN_SIG_* values in <sys signalvar.h=""> */ #define SIG_DFL (void (*)(int))0 #define SIG_IGN (void (*)(int))1 #define SIG_HOLD (void (*)(int))5 #define SIG_ERR ((void (*)(int))-1) #else /* DO NOT REMOVE THE COMMENTED OUT int: fixincludes needs to see them */ #define SIG_DFL (void (*)(/*int*/))0 #define SIG_IGN (void (*)(/*int*/))1 #define SIG_HOLD (void (*)(/*int*/))5 #define SIG_ERR ((void (*)(/*int*/))-1) #endif </sys> |