macOS Mojave 10.14.3
Xcode10.1
iPhone6S 10.0.1
Xcode
菜单 > Window
> Devices and Simulators
选择设备并查看设备日志(View Device Logs
)
设置 > 隐私 > 诊断与用量 > 诊断与用量数据
Incident Identifier
: 崩溃日志的唯一标识CrashReporter Key
: 匿名的设备标识Process
:进程名Path
:二进制文件路径Identifier
:包名Version
:应用版本号Code Type
: 目标架构Role
:进程终止时进程被赋予的task_role
枚举值Incident Identifier: F21EC10C-018D-494F-997D-E9C9D82B2F7F
CrashReporter Key: ab7fcdf6938542fd82446362e0481f7fddba141f
Hardware Model: iPhone6,2
Process: JACrash [27195]
Path: /private/var/containers/Bundle/Application/EDDDCB8E-75CE-4638-84CA-5B7971F6EFE0/JACrash.app/JACrash
Identifier: com.ishepherdme.JACrash
Version: 1 (1.0)
Code Type: ARM-64 (Native)
Role: Foreground
Parent Process: launchd [1]
Coalition: com.ishepherdme.JACrash [4182]
Date/Time: 2019-02-08 13:03:58.7771 +0800
Launch Time: 2019-02-08 13:03:58.3811 +0800
OS Version: iPhone OS 10.0.1 (14A403)
Report Version: 104
Triggered by Thread
: 产生崩溃的线程Exception Type
: 崩溃类型Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0
Application Specific Information
:在进程终止时框架捕获的错误信息Application Specific Information:
abort() called
Filtered syslog:
None found
罗列崩溃时每个线程的调用栈情况
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x000000018af0e014 __pthread_kill + 8
1 libsystem_pthread.dylib 0x000000018afd5460 pthread_kill + 112
2 libsystem_c.dylib 0x000000018ae823f4 abort + 140
3 libc++abi.dylib 0x000000018a94d2d4 __cxa_bad_cast + 0
4 libc++abi.dylib 0x000000018a96acc0 default_unexpected_handler+ 126144 () + 0
5 libobjc.A.dylib 0x000000018a978844 _objc_terminate+ 34884 () + 124
6 libc++abi.dylib 0x000000018a96766c std::__terminate(void (*)+ 112236 ()) + 16
7 libc++abi.dylib 0x000000018a967234 __cxa_rethrow + 144
8 libobjc.A.dylib 0x000000018a97871c objc_exception_rethrow + 44
9 CoreFoundation 0x000000018be1a0bc CFRunLoopRunSpecific + 560
10 UIKit 0x0000000191df37cc -[UIApplication _run] + 608
11 UIKit 0x0000000191dee550 UIApplicationMain + 208
12 JACrash 0x000000010007de90 0x100078000 + 24208
13 libdyld.dylib 0x000000018adfc5b8 start + 4
列出崩溃线程的线程状态。这是一个寄存器列表及其执行停止时的值。在阅读崩溃报告时,无需了解线程状态,但可以使用此信息更好地了解崩溃的情况。
Thread 0 crashed with ARM Thread State (64-bit):
x0: 0x0000000000000000 x1: 0x0000000000000000 x2: 0x0000000000000000 x3: 0x00000001740e9737
x4: 0x000000018a96bbc3 x5: 0x000000016fd87520 x6: 0x000000000000006e x7: 0xffffffffffffffec
x8: 0x0000000008000000 x9: 0x0000000004000000 x10: 0x000000000000000b x11: 0x0000000000000010
x12: 0x000000018ae99792 x13: 0x0000000000000000 x14: 0x0000030000000300 x15: 0x0000000000000000
x16: 0x0000000000000148 x17: 0x0000000000000000 x18: 0x0000000000000000 x19: 0x0000000000000006
x20: 0x00000001b0bf8c40 x21: 0x000000016fd87520 x22: 0x00000001b0bffbb8 x23: 0x0000000000000001
x24: 0x0000000170011110 x25: 0x0000000000000000 x26: 0x0000000000000001 x27: 0x0000000000000000
x28: 0x000000016fd87b80 fp: 0x000000016fd87480 lr: 0x000000018afd5460
sp: 0x000000016fd87460 pc: 0x000000018af0e014 cpsr: 0x00000000
进程二进制文件加载的地址区间,动态库加载的地址区间
Binary Images:
0x100078000 - 0x10007ffff JACrash arm64 <2fd461c16e7239489a037c6c1141c134> /var/containers/Bundle/Application/A55333A1-CD62-41A2-AE96-F3411ECD3447/JACrash.app/JACrash
0x10009c000 - 0x10009ffff MobileSubstrate.dylib arm64 <3134cfb2f722310ea2c742ae4dc131ab> /Library/MobileSubstrate/MobileSubstrate.dylib
0x1000a8000 - 0x1000affff libswiftCoreFoundation.dylib arm64 <47deeaa1967b3e339dfcb48535a994e1> /var/containers/Bundle/Application/A55333A1-CD62-41A2-AE96-F3411ECD3447/JACrash.app/Frameworks/libswiftCoreFoundation.dylib
0x1000bc000 - 0x1000cbfff libswiftCoreGraphics.dylib arm64 <25fe91aa901b3cf6a443b498012ab5af> /var/containers/Bundle/Application/A55333A1-CD62-41A2-AE96-F3411ECD3447/JACrash.app/Frameworks/libswiftCoreGraphics.dylib
0x1000f0000 - 0x1000f7fff libswiftCoreImage.dylib arm64
....
Exception Type
)Bad Memory Access [EXC_BAD_ACCESS // SIGSEGV // SIGBUS]
)尝试访问了非法的内存地址,或访问了受保护的地址
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x000000064229beb8
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [0]
Triggered by Thread: 0
比如在MRC
环境下尝试发送消息给已释放的对象,调用栈的特点是objc_msgSend
/objc_release
在调用栈顶
Abnormal Exit [EXC_CRASH // SIGABRT]
)@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self callCrashMethod];
}
- (void)callCrashMethod {
[self arrayOutOfBounds];
}
- (void)arrayOutOfBounds {
NSArray *arr = @[@"0",@"1"];
NSLog(@"%@",arr[2]);
}
@end
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0
崩溃会直接到main
,因为调用栈中包含objc_exception_rethrow
栈帧,根据参考1,进行如下的配置,设置异常的断点
The Exception Breakpoint
So how do you find the line in the code that made the app crash? Well, whenever you get a stacktrace like this, an exception was thrown by the app. (You can tell because one of the functions in the call stack is named objc_exception_rethrow.)
Trace Trap [EXC_BREAKPOINT // SIGTRAP]
)这个异常是为调试器提供在进程执行的特定点中断进程的机会。
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x000000010006e588
Termination Signal: Trace/BPT trap: 5
Termination Reason: Namespace SIGNAL, Code 0x5
Terminating Process: exc handler [0]
Triggered by Thread: 0
Illegal Instruction
)进程试图执行非法或未定义指令。这个进程可能试图通过一个配置错误的函数指针,跳到一个无效的地址。
Exception Type: EXC_CRASH (SIGILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Illegal instruction: 4
Termination Reason: Namespace SIGNAL, Code 0x4
Terminating Process: neteasemusic [6562]
Triggered by Thread: 0
Killed[SIGKILL]
)Exception Type: EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: Namespace SPRINGBOARD, Code 0x8badf00d
Triggered by Thread: 0
Resource Limit [EXC_RESOURCE]
)这个进程超出了资源消耗的限制。
来自参考3
dSYM
文件DWARF
即Debugging with Attributed Record Formats
,Xcode
使用它来生成符号表,生成的符号表放在.dSYM
文件中,在Debug
模式下,默认不会生成.dSYM
文件,可以在Build Settings
中进行设置
编译后,在工程中Product
目录下,选择应用程序,Show in Finder
,会发现生成了应用的.dSYM
文件
UUID
Binary Images:
0x1000f8000 - 0x1000fffff JACrash arm64 <2fd461c16e7239489a037c6c1141c134> /var/containers/Bundle/Application/7B72F18F-930E-42CB-B69C-FED75161A03F/JACrash.app/JACrash
UUID:2fd461c16e7239489a037c6c1141c134
% dwarfdump --uuid path/to/Your.app.dSYM/Contents/Resources/DWARF/JACrash
...
UUID: 2FD461C1-6E72-3948-9A03-7C6C1141C134 (arm64) /Users/Jason/Library/Developer/Xcode/DerivedData/JACrash-bntjxfwsvrraeuevozrbvraorxqv/Build/Products/Debug-iphoneos/JACrash.app.dSYM/Contents/Resources/DWARF/JACrash
两者UDID
一致即可
% atos -o path/to/Your.app.dSYM/Contents/Resources/DWARF/Your -arch arm64 -l 0x1000f8000 0x1000fdda8
-[ViewController arrayOutOfBounds] (in JACrash) (ViewController.m:33)
0x1000f8000
: 运行时应用基地址
0x1000fdda8
: 运行时崩溃地址(待符号化的地址)
bitcode
支持bitcode
的情况下,因为最终的二进制文件由Apple Store
后台生成,本地是没有对应的.dSYM
文件,可以从Xcode
或iTunes Connect
上下载
Hopper
如果没有.dSYM
文件,但有崩溃日志的情况时
崩溃地址 = 基地址 + ASLR
+ 方法偏移地址
方法相对基地址的偏移地址是不变的,因此只要把ASLR
从崩溃地址中移除,再加上方法的偏移地址即可
用hopper
找出基地址,再加上方法偏移地址
/// 函数指针,用于自定义捕获异常后要进行的操作
typedef void NSUncaughtExceptionHandler(NSException *exception);
FOUNDATION_EXPORT NSUncaughtExceptionHandler * _Nullable NSGetUncaughtExceptionHandler(void);
FOUNDATION_EXPORT void NSSetUncaughtExceptionHandler(NSUncaughtExceptionHandler * _Nullable);
在程序启动时加上一个异常捕获监听,用来处理程序崩溃时的回调动作
void exceptionHandler(NSException *exception) {
NSLog(@"%@", [exception reason]);
NSLog(@"%@", [exception userInfo]);
NSLog(@"%@", [exception callStackSymbols]);
}
int main(int argc, char * argv[]) {
NSSetUncaughtExceptionHandler(&exceptionHandler);
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}