一、 crash log 格式
圖檔來源:www.cnblogs.com/ciml/p/7422…
基本資訊:
Binary Images :
大概分三部分吧,1、基本資訊2、線程3、Binary Images(二進制檔案)
1、基本資訊
重點看:
1、 CodeType: Arm-64
2、
Exception Type
:崩潰類型
3、
Triggered by Thread: 1
崩潰的是哪個線程,那麼線程就可以重點看對應的 thread 就好了。
2、線程
主要四列
第一列:調用堆棧序号 第二列:二進制包名 第三列:二進制運作時的位址 第四列: 二進制的基位址加偏移量(偏移量是十進制,計算時要轉為16進制)
計算規則:運作時位址 = 起始位址 + 偏移量(轉為16進制)
每個二進制包的起始位址是不一樣的,在 crash log 底部會列出所有的二進制包的名字,路徑和 起始位址和結束位址
正常情況下根據 自己的 app 的起始位址,可以通過
atos
和
dSYM
檔案,算出對應的代碼是什麼。
atos
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、iPhone2、iPhone3G armv7:iPhone4、iPhone4S armv7s:iPhone5、iPhone5C arm64:iPhone5S
3、Binary Images
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
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 了
三、slide address
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
複制代碼
最後
參考連結:
www.cnblogs.com/feng9exe/p/…
www.cnblogs.com/feng9exe/p/…
www.cnblogs.com/ciml/p/7422…
www.jianshu.com/p/035d9e863…
www.jianshu.com/p/0a1c029e9…
www.jianshu.com/p/e66fc953a…
foggry.com/blog/2015/0…
developer.apple.com/library/arc…
www.xuyanlan.com/2019/01/14/…
轉載于:https://juejin.im/post/5c8f4bfd5188252d8e278aa3