iOS 崩溃排查技巧:如何获取系统库源码

Python实战社群

Java实战社群

长按识别下方二维码,按需求添加

扫码关注添加客服

进Python社群▲

扫码关注添加客服

进Java社群

作者丨酷酷的哀殿,百度 iOS 开发工程师

来源丨老司机技术周报(ID:LSJCoding)

APP 崩溃会导致用户体验下降,严重时甚至会导致用户卸载 APP。我希望从实际问题中去分享一些我日常工作上的小技巧,希望可以帮助到大家。

今天要分享的是「如何获取系统库源码」,问题源自于一位朋友遇到了一个系统库相关的 crash,一直无法定位到具体原因,所以想了解一下「如何根据 iOS 崩溃日志获取对应系统库源码」,正好我之前也遇到过类似的问题,所以和大家分享一下我的一些办法。

基础术语对齐

按照惯例,为了方便提高效率,避免歧义,第一部分是基础术语对齐。

如下,我们从官方文档 Examining the Fields in a Crash Report 的截取部分标准的崩溃日志进行讲解。

Incident Identifier: 6156848E-344E-4D9E-84E0-87AFD0D0AE7B
CrashReporter Key:   76f2fb60060d6a7f814973377cbdc866fffd521f
Hardware Model:      iPhone8,1
Process:             TouchCanvas [1052]
Path:                /private/var/containers/Bundle/Application/51346174-37EF-4F60-B72D-8DE5F01035F5/TouchCanvas.app/TouchCanvas
Identifier:          com.example.apple-samplecode.TouchCanvas
Version:             1 (3.0)
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]
Coalition:           com.example.apple-samplecode.TouchCanvas [1806]

Date/Time:           2020-03-27 18:06:51.4969 -0700
Launch Time:         2020-03-27 18:06:31.7593 -0700
OS Version:          iPhone OS 13.3.1 (17D50)


22  libdyld.dylib                     0x00000001b6728360 start + 4

  • OS Version:系统版本号,13.3.1

  • OS Build Version:系统编译版本号,17D50

  • 二进制文件:二进制文件名,libdyld.dylib

为了方便方便区分 13.3.1 与 17D50,本文的概念与官方概念存在略微差异,敬请理解。

另外,我们下面还会用以下术语:

  • PROJECT_NAME:项目名,比如 dyld

  • PRODUCT_NAME,构建产物名称,通常与 PROJECT_NAME一致

    • 比如 libdyld.dylib就是由 lib + dyld + .dylib 组合而成,dyld 就是 PRODUCT_NAME

  • CURRENT_PROJECT_VERSION:项目版本号

根据OS Version定位源码

操作步骤:

  1. 结合 Xcode 发布文档,我们推测 iPhone OS 13.3.1 对应的 macOS 版本可能10.15.2

  2. 在 https://opensource.apple.com/ 找到对应的版本链接:

  • iOS 13.3.1

  • macOS 10.15.2

  • 根据二进制文件名libdyld.dylib 猜测对应的PROJECT_NAMEdyld

  • 对照  macOS 10.15.2 ,可以猜测CURRENT_PROJECT_VERSION733.8

  • 点击dyld-733.8右侧的 ⬇️ 按钮进行下载

  • 如果没有找到对应的源码文件,则尝试查找上一个系统版本,比如

    • [macOS 10.15.1] (https://opensource.apple.com/release/macos-10151.html)、

    • [macOS 10.15] (https://opensource.apple.com/release/macos-1015.html)

    经过实际测试,大部分情况都可以根据二进制文件都能够找到对应的源码。

    但是仍然会遇到以下两类问题:

    1.CURRENT_PROJECT_VERSION 不够精确。

    对于 iPhone OS 13.3.1,我们无法准确得知对应的macOS 系统版本号

    2.部分情况无法根据二进制文件反推出对应的 PROJECT_NAME

    比如,我们无法根据libsystem_asl.dylib找到与 system_asl 相关的源码

    优化一

    根据OS Build Version 获取 PROJECT_VERSION

    操作步骤:

    1、在 ~/Library/Developer/Xcode/iOS\ DeviceSupport目录下查找到对应的二进制文件

    cd ~/Library/Developer/Xcode/iOS\ DeviceSupport 
    find . -name libdyld.dylib
    

    输出:

    ./14.0 (18A373) arm64e/Symbols/usr/lib/system/libdyld.dylib
    

    2、根据第1步的结果,我们发现本机只有14.0 (18A373) arm64e版本,与我们需要查找的 13.3.1 (17D50)不符。所以,尝试通过搜索引擎查找。

    • 比如 iOS-System-Symbols 就维护了超过100个系统符号文件目录的压缩版本。

    3、通过 llvm-objdump 命令打印该二进制文件相关的二进制库信息

    llvm-objdump -m --dylibs-used ./Symbols/usr/lib/system/libdyld.dylib
    

    输出:

    ./Symbols/usr/lib/system/libdyld.dylib:
     /usr/lib/system/libdyld.dylib (compatibility version 1.0.0, current version 828.4.0)
     /usr/lib/system/libsystem_platform.dylib (compatibility version 1.0.0, current version 254.0.0, upward)
     /usr/lib/system/libsystem_malloc.dylib (compatibility version 1.0.0, current version 317.0.1, upward)
     /usr/lib/system/libsystem_c.dylib (compatibility version 1.0.0, current version 1439.0.3, upward)
     /usr/lib/system/libsystem_pthread.dylib (compatibility version 1.0.0, current version 454.0.0, upward)
     /usr/lib/system/libxpc.dylib (compatibility version 1.0.0, current version 2038.0.15, upward)
     /usr/lib/system/libsystem_blocks.dylib (compatibility version 1.0.0, current version 78.0.0, upward)
     /usr/lib/system/libsystem_kernel.dylib (compatibility version 1.0.0, current version 7195.0.43, upward)
     /usr/lib/system/libsystem_sandbox.dylib (compatibility version 1.0.0, current version 1441.0.4, upward)
     /usr/lib/system/libdispatch.dylib (compatibility version 1.0.0, current version 1271.0.4, upward)
     /usr/lib/system/libcorecrypto.dylib (compatibility version 1.0.0, current version 1000.0.5, upward)
     /usr/lib/system/libcompiler_rt.dylib (compatibility version 1.0.0, current version 102.3.0, upward)
    

    从输出的第2行,可以发现 libdyld.dylib对应的CURRENT_PROJECT_VERSION828.4.0

    优化二

    根据 OS Build Version 获取 PROJECT_NAME

    操作步骤:

    1、以 libsystem_asl.dylib为例,先通过find命令定位二进制文件的位置

    find . -name libsystem_asl.dylib
    

    输出:

    ./Symbols/usr/lib/system/libsystem_asl.dylib
    

    2、通过 llvm-objdump -s 对整个二进制文件进行 dump 操作,并通过 grep 命令筛选 p __const的内容

    考虑到下载系统符号文件会占用较大的空间,作者没有下载17D50对应的符号文件,而是以 18A373 为例进行说明

    llvm-objdump -s ./Symbols/usr/lib/system/libsystem_asl.dylib | grep "Contents of p __const" -A 3
    

    输出:

    Contents of p __const:
     19a1c19f0 40282329 50524f47 52414d3a 61736c20  @(#)PROGRAM:asl
     19a1c1a00 2050524f 4a454354 3a737973 6c6f672d   PROJECT:syslog-
     19a1c1a10 3338350a 00000000 00000000 00107840  385...........x@
    --
    Contents of p __const:
     1d1641d18 00000000 00000000 20000000 00000000  ........ .......
     1d1641d28 821b1c9a 01001000 00000000 00000000  ................
     1d1641d38 ba1c1c9a 01000800 6c1c1c9a 01000800  ........l.......
    --
    Contents of p __const:
     1db1b7de8 00000000 00000000 00d91a1a 00005880  ..............X.
     1db1b7df8 00000000 00000000 00000000 00000000  ................
     1db1b7e08 00000000 00000000 00000000 00000000  ................
    

    我们很容易发现以下内容:

    @(#)PROGRAM:asl PROJECT:syslog-385
    

    实际上,根据 Xcode提供的Build System资料,我们可以得到以下信息:

    • PRODUCT_NAME: asl

    • PROJECT_NAMEsyslog

    • PROJECT_VERSION385

    3、根据上一步的结果结果,直接打开 https://opensource.apple.com/tarballs/syslog 目录并选择对应的版本。

    在作者写本文时14.0 (18A373) arm64e 对应的 syslog-385 还未开源。所以,我们只能下载到 syslog-377.40.1.tar.gz

    总结

    本文分享了两种特殊的技巧定位崩溃日志对应的源码。

    如果有读者发现了其它方案,欢迎加入我们的微信群,一起参与讨论。


    优点缺点
    系统版本号简单,无需对应的符号文件* 无法无法准确定位对应源码工程名问题
    * 存在无法准确定位源码版本问题
    系统编译版本号* 无法无法准确定位对应源码工程名问题
    * 存在无法准确定位源码版本问题
    需要下载对应的符号文件(通常在1G以上)

    程序员专栏 扫码关注填加客服 长按识别下方二维码进群
    
    

    近期精彩内容推荐:  

     程序员写的这一行代码,被国家博物馆收藏了

     2020 年 9 月程序员工资统计,我扯后腿了~

     提高国内访问 GitHub 的速度的 9 种方案

     Python是强类型语言,还是弱类型语言?

    在看点这里好文分享给更多人↓↓

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值