iOS 如何根据错误的堆栈地址定位到代码?

现在有很多的第三方服务SDK都支持错误堆栈信息符号化,常见的友盟、bugly等
但是我们只知道通过他的操作步骤,定位具体的代码,
那么如何通过自己的方式定位呢?

首先我们每次通过Xcode打包的时候都会产生一个.dsym文件,你在这里可以找到

iOS 如何根据错误的堆栈地址定位到代码?_第1张图片

然后再右键-->显示包内容,就可以找到当前打包出来的dsym文件了,如下:

iOS 如何根据错误的堆栈地址定位到代码?_第2张图片

我们可以用命令行检查一下dsym 所支持的UUID,此UUID可以确定设备的架构类型(arm64, armv7, armv7s 等)
通过命令行:dwarfdump --uuid xxx(.app.dsym)

iOS 如何根据错误的堆栈地址定位到代码?_第3张图片

最后我们可以利用这个文件定位错误代码的具体的位置。
定位错误命令行:
xcrun atos -o xxx(.dsym路径下的APP) -arch armv7/armv7s/arm64(选其一) -l xxx(起始地址) xxx(运行地址)

iOS 如何根据错误的堆栈地址定位到代码?_第4张图片

注意在错误堆栈信息里面的地址:结束地址需要转换成十六进制

iOS 如何根据错误的堆栈地址定位到代码?_第5张图片

在此,给大家提供一个获取APP的运行时的UUID方法,方便以后分析和定位错误代码,将当前版本的UUID和错误的堆栈信息可以发给开发者或者是上传到服务器,这样在开发拿到你的信息之后,通过上面的步骤就可以快速定位错误代码了

#import 
#import 

static NSUUID *ExecutableUUID(void)
{
    const struct mach_header *executableHeader = NULL;
    for (uint32_t i = 0; i < _dyld_image_count(); i++)
    {
        const struct mach_header *header = _dyld_get_image_header(i);
        if (header->filetype == MH_EXECUTE)
        {
            executableHeader = header;
            break;
        }
    }
    if (!executableHeader)
        return nil;

    BOOL is64bit = executableHeader->magic == MH_MAGIC_64 || executableHeader->magic == MH_CIGAM_64;
    uintptr_t cursor = (uintptr_t)executableHeader + (is64bit ? sizeof(struct mach_header_64) : sizeof(struct mach_header));
    const struct segment_command *segmentCommand = NULL;
    for (uint32_t i = 0; i < executableHeader->ncmds; i++, cursor += segmentCommand->cmdsize)
    {
        segmentCommand = (struct segment_command *)cursor;
        if (segmentCommand->cmd == LC_UUID)
        {
            const struct uuid_command *uuidCommand = (const struct uuid_command *)segmentCommand;
            return [[NSUUID alloc] initWithUUIDBytes:uuidCommand->uuid];
        }
    }
    return nil;
}
运行UUID参考资料:
http://stackoverflow.com/questions/19848567/how-to-get-the-build-uuid-in-runtime-and-the-image-base-address




你可能感兴趣的:(ios异常,ios,运行UUID)