天天看點

回顧 crash log 分析

一、 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

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