图片来源:www.cnblogs.com/ciml/p/7422…html
基本信息:xcode
Binary Images : bash
大概分三部分吧,一、基本信息二、线程三、Binary Images(二进制文件)架构
重点看:app
一、 CodeType: Arm-64dom
二、Exception Type
:崩溃类型ide
三、Triggered by Thread: 1
崩溃的是哪一个线程,那么线程就能够重点看对应的 thread 就行了。函数
主要四列工具
第一列:调用堆栈序号 第二列:二进制包名 第三列:二进制运行时的地址 第四列: 二进制的基地址加偏移量(偏移量是十进制,计算时要转为16进制)ui
计算规则:运行时地址 = 起始地址 + 偏移量(转为16进制)
每一个二进制包的起始地址是不同的,在 crash log 底部会列出全部的二进制包的名字,路径和 起始地址和结束地址
正常状况下根据 本身的 app 的起始地址,能够经过 atos
和 dSYM
文件,算出对应的代码是什么。
atos
命令的参数:
-arch : 对应的就是Code Type,`Arm-64`对应的就是 arm64。
-o : 二进制路径
-l : 运行时内存地址
复制代码
能够参考下面的图片:
atos -arch arm64 -o TheElements.app.dSYM/Contents/Resources/DWARF/TheElements -l 0x1000e4000 0x00000001000effdc
算出结果:
-[AtomicElementViewController myTransitionDidStop:finished:context:]
复制代码
atos
后面的-l
参数能够跟好几个地址,解析出对应的堆栈,可是第一个应该是基地址,例如:
atos -o ***.ipa.dSYM/Contents/Resources/DWARF/*** -arch arm64 -l 0x102fa8000 0x0000000103c2cd7c 0x0000000103bff898 0x0000000103bfd438
输出:
-[BLYCrashManager didCrashAccidentHappened] (in ***) + 204
BLYCrashHandlerCallback (in ***) + 432
BLYBSDSignalHandlerCallback (in ***) + 92
复制代码
附上 Code Type 可能的值:
其中arm64是指架构类型,这个就须要根据APP是在哪一个手机上运行决定的,这里有个型号对应表 armv6:iPhone、iPhone二、iPhone3G armv7:iPhone四、iPhone4S armv7s:iPhone五、iPhone5C arm64:iPhone5S
0x100004000 - 0x10000ffff CrashTest arm64 <5fc8820b297631d087e5e665b261ed0c> /var/mobile/Containers/Bundle/Application/D8F09771-5B65-4403-A19C-CE77DAF32623/CrashTest.app/CrashTest
0x120070000 - 0x120097fff dyld arm64 <f958ba064181388a9658f927da42e9e7> /usr/lib/dyld
复制代码
分为5列:
第1列: 地址区间 ,二进制文件运行时 其实地址(基址)和结束地址
第2列:二进制包名,app 的名字,动态连接库等等
第3列:二进制 架构类型: arm64
第4列:UUID
第5列:二进制路径
symbolicatecrash
xcode 提供的一个命令,能够符号化 crash log。 这个脚本的地址在:
/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash
复制代码
能够拷贝到 usr/local/bin
目录下,这样就能够全局使用了,不用每次都输入那么一长串。
cp /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash /usr/local/bin
复制代码
把 crash.log 和 dSYM 文件拷贝到一个目录下面执行:
symbolicatecrash ***.crash ***.dSYM > ***_symbol.crash
复制代码
执行若是报错:
Error: "DEVELOPER_DIR" is not defined at /usr/local/bin/symbolicatecrash line 69.
复制代码
则须要执行:
export DEVELOPER_DIR="/Applications/XCode.app/Contents/Developer"
复制代码
若是执行成功,就能够在当前目录获得符号化的 crashlog 了
ASLR
技术Address space layout randomization
,ASLR经过将系统可执行程序随机装载到内存里,从而防止缓冲区溢出攻击 因为 ASLR 的缘故,致使 程序crash后生成的crash log 中的 stack address 与 对应的 symbol address 不一致,有一个偏移量 slide,slide是程序装在时随机生成的随机数。 很简单 symble address
= stack address
-slide
;
引入新的概念:
stack address
: 程序运行时线程栈中 全部 函数调用的地址
symble address
: dsym文件中函数符号对应的地址,用此地址 在 dsym 文件中能够 查出对应的 符号信息。 无 ASLR 机制时 stack address
等于symble address
。
slide address
获取代码:
/** 获取加载偏移地址 */
long long getSlide()
{
long long slide = 0;
for (uint32_t i = 0; i < _dyld_image_count(); i++) {
if (_dyld_get_image_header(i)->filetype == MH_EXECUTE) {
slide = _dyld_get_image_vmaddr_slide(i);
break;
}
}
return slide;
}
复制代码
atos
和 symbolicatecrash
不须要获取 Slide Address
,只要知道运行时地址就能够符号化。使用最为简单方便。
还有其余工具如:lldb
和 Dwarfdump
就须要复杂点的计算了。
由于它们采用文件地址(0x10000ECC4),所以您须要考虑为这些工具设置偏移量。 从 dSYM 获取偏移量的一种方法是使用“otool”,它能够与 OSX 上的 XCode 开发人员工具一块儿使用。
您须要查找 LC_SEGMENT_64(arm64)或 LC_SEGMENT(armv7,armv7s)段和“vmaddr”条目。 对于iOS,对于32位一般为0x4000,对于64位架构一般为0x100000000。
otool -l ApteligentExampleApp.dSYM > ApteligentExampleApp.otool.output
Load command 3
cmd LC_SEGMENT_64
cmdsize 1032
segname __TEXT
vmaddr 0x0000000100000000
复制代码
参考连接: