解析奔溃日志的文章有很多,但是满足我的需求真的很少,这边我主要写我遇到的坑点收集。
1 获取奔溃日志的符号表堆栈地址 (Base Address)
static NSString *GetLoadAddres(void) {
NSString *imageLoadAddress = @"";
for (uint32_t i = 0; i < _dyld_image_count(); i++) {
const struct mach_header* imageHeader = _dyld_get_image_header(i);
if (imageHeader == NULL) {
continue;
}
if (imageHeader->filetype == MH_EXECUTE) {
imageLoadAddress = [NSString stringWithFormat:@"0x%llX", (uint64_t)imageHeader];
break;
}
}
return imageLoadAddress;
}
如何验证符号表堆栈地址
是否正确:
当你收到一条奔溃信息如下
5 Demo 0x0000000100bd15ac Demo + 21932
可以看到这个奔溃信息的堆栈地址和偏移值。
堆栈地址:0x0000000100bd15ac
偏移值:21932
符号表堆栈地址
= 堆栈地址
- 偏移值
这样就可以验证你的符号表堆栈地址
的正确性了。
2 获取CPU Type
#include <mach/mach_host.h>
- (NSString *)cpuType {
host_basic_info_data_t hostInfo;
mach_msg_type_number_t infoCount;
infoCount = HOST_BASIC_INFO_COUNT;
host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount);
NSString *architecture = @"";
if (hostInfo.cpu_type == CPU_TYPE_ARM64)
architecture = @"arm64";
else if (hostInfo.cpu_type == CPU_TYPE_ARM)
{
///WJDeviceInfo 这个库我自己封装的 这边只是获取设备名如: iPhone5,1 等等自己搜
NSString* device = WJDeviceInfo.currentDevice.deviceName;
NSInteger modelNo = [[device substringFromIndex:device.length - 1] integerValue];
if (([device hasPrefix:@"iPhone5,"] && modelNo >= 1 && modelNo <= 4) ||
([device hasPrefix:@"iPad3,"] && modelNo >= 4 && modelNo <= 6))
architecture = @"armv7s";
else
architecture = @"armv7";
}
return architecture;
}
3 单条日志解析
粗略介绍命令
可以使用 dwarfdump
校验出app和dSYM,是否一致。
> dwarfdump --uuid <dSYM地址>
可以使用atos
解析奔溃日志
> atos -o <dSYM地址> -arch <CPUType> -l <符号表堆栈地址 > <奔溃堆栈地址>