回顾 crash log 分析

本文主要介绍iOS崩溃日志(crash log)的格式,包括基本信息、线程和二进制文件等内容,还讲解了xcode符号化crash log的方法,以及因ASLR机制导致的偏移量问题,最后提及从dSYM获取偏移量的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、 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 的起始地址,可以通过 atosdSYM 文件,算出对应的代码是什么。

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 addressstack addressslide

引入新的概念:

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;
}
复制代码

atossymbolicatecrash 不需要获取 Slide Address,只要知道运行时地址就可以符号化。使用最为简单方便。

还有其他工具如:lldbDwarfdump 就需要复杂点的计算了。

因为它们采用文件地址(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

<think>我们正在回答用户关于在AndroidStudio中过滤logcat日志的问题。用户明确提到了参考站内引用,因此我们需要结合引用内容来回答。根据引用内容:引用[1]:提到了使用level过滤器查看各个等级的日志,以及一些其他功能(如管理.gradle路径、手机投屏等)。引用[2]:介绍了新版AndroidStudioLogcat的筛选日志方法,特别是按照包名过滤(package:mine)以及使用正则表达式等。引用[3]:说明了在AndroidStudio的logcat中可以使用键值对搜索,并且可以按Ctrl+Space获取建议。用户上一次的问题是关于logcat日志的分析,我们已经给出了详细的步骤。现在用户具体询问在AndroidStudio中如何过滤logcat日志。因此,我们应重点介绍AndroidStudio中logcat的过滤方法,包括:1.按日志级别(Level)过滤2.按包名(Package)过滤3.按标签(Tag)过滤4.按关键字(Keyword)过滤5.使用正则表达式(Regex)过滤6.使用键值对搜索(如tag:xxx,level:error等)同时,我们可以参考引用[2]中提到的package:mine(当前包名)等具体用法。回答结构:1.打开logcat窗口2.介绍过滤栏(Filter)的各个过滤方式3.分别详细说明每种过滤方式的使用方法,并举例4.提到引用中给出的技巧(如Ctrl+Space获取建议)注意:用户使用的是新版AndroidStudio(如2022.3.1及以上),因此我们按照新版界面来介绍。具体步骤:步骤1:打开Logcat窗口步骤2:认识过滤栏的各个部分(有多个过滤条件输入框,以及一个日志级别选择下拉框)步骤3:按包名过滤(使用package:mine或者输入包名)步骤4:按日志级别过滤(选择Verbose,Debug,Info,Warn,Error,Assert)步骤5:按标签(Tag)过滤(使用tag:xxx,或者直接输入标签名)步骤6:按关键字过滤(在查询框中输入关键字)步骤7:使用正则表达式(勾选Regex选项,然后在查询框输入正则表达式)步骤8:使用组合条件(例如同时按包名和标签过滤:package:minetag:MyTag)步骤9:使用键值对搜索(如level:E,message:"crash"等)同时,我们可以提到引用[3]中的键值对搜索和Ctrl+Space获取建议的功能。最后,生成相关问题。注意:引用标记要自然地添加在回答中对应的位置。</think>### Android Studio logcat 日志过滤方法详解 在 Android Studio 中高效过滤 logcat 日志是开发调试的关键。以下是基于最新版 Android Studio (2022.3+) 的实用过滤方法,结合官方文档和开发者实践: #### 一、基础过滤方法 1. **按日志级别过滤** - 点击 Logcat 窗口顶部的 **日志级别下拉菜单** - 可选级别:`Verbose` (全部), `Debug`, `Info`, `Warn`, `Error`, `Assert` - 示例:选择 `Error` 只显示崩溃和严重错误[^1] 2. **按包名过滤** - 在查询框输入:`package:mine` (自动过滤当前运行模块的日志) - 指定包名:`package:com.example.app` - 排除包名:`-package:com.thirdparty.lib`[^2] 3. **按标签(Tag)过滤** - 精确匹配:`tag:MyActivity` - 模糊匹配:`tag:^Auth.*`(正则匹配以"Auth"开头的 tag) - 排除标签:`-tag:Test` #### 二、高级过滤技巧 4. **组合条件查询** 使用 **键值对+布尔逻辑** 构建复杂查询: ```logcat package:mine level:error tag:Network ``` 表示:当前包名下,标签为 Network 的错误日志 5. **正则表达式过滤** - 启用正则:点击查询框右侧的 **.* 图标** - 示例:`message:.*NullPointer.*` (查找包含空指针异常的消息) 6. **实时建议功能** 在查询框中按 `Ctrl+Space`(Win/Linux)或 `Cmd+Space`(Mac)触发智能建议: - 自动补全标签名 - 提示可用过滤键(package/tag/level等)[^3] #### 三、实用场景示例 | 场景 | 过滤命令 | 说明 | |---------------------|-----------------------------|-------------------------------| | 排查崩溃 | `level:error package:mine` | 当前APP的错误日志 | | 分析网络请求 | `tag:OkHttp` | 过滤OkHttp库的日志 | | 监控数据库操作 | `tag:Room message:INSERT` | 数据库插入操作日志 | | 排除测试日志 | `-tag:Testing` | 屏蔽所有测试相关的日志 | #### 四、最佳实践建议 1. **保存过滤方案** 点击过滤栏右侧的 **+** 图标,保存常用过滤条件,一键切换不同调试场景。 2. **颜色标识优化** 右键日志条目 → `Edit Log Configuration` → 为特定 tag/级别设置高亮颜色。 3. **避免日志截断** 当长日志被截断时: - 在查询框添加 `is:long` 显示完整日志 - 或双击日志条目展开详情 > 通过组合使用这些过滤技巧,可快速定位:崩溃堆栈、性能瓶颈(如`Choreographer`跳帧警告)、自定义日志点等关键信息[^1][^2][^3]。 --- ### 相关问题 1. 如何为特定日志标签设置永久高亮颜色? 2. logcat 中 `is:crash` 和 `level:error` 有什么区别? 3. 如何查看被截断的长日志的完整内容? 4. 能否通过 logcat 过滤特定时间段的日志? 5. Android Studio 的 logcat 过滤器和 adb logcat 命令如何对应?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值