通过崩溃trace来查找问题原因

本文详细介绍了如何利用UMeng获取的崩溃信息进行故障定位,并通过反编译技术找到二进制对应的源码位置,帮助开发者有效分析原因。

这里我们以UMeng捕获的错误信息举例:

从友盟中, 我们可能会得到如下信息:

Application received signal SIGSEGV

(null)
(
	0   CoreFoundation                      0x359348a7 __exceptionPreprocess + 186
	1   libobjc.A.dylib                     0x37cdb259 objc_exception_throw + 32
	2   CoreFoundation                      0x35934789 +[NSException raise:format:] + 0
	3   CoreFoundation                      0x359347ab +[NSException raise:format:] + 34
	4   NxxMovie                          0x1153b9 _mh_execute_header + 1131449
	5   libsystem_c.dylib                   0x32d407e3 _sigtramp + 38
	6   NxxMovie                          0x390fb _mh_execute_header + 229627
	7   CoreFoundation                      0x358931fb -[NSObject performSelector:withObject:] + 42
	8   NxxMovie                          0x175a5 _mh_execute_header + 91557
	9   CoreFoundation                      0x358931fb -[NSObject performSelector:withObject:] + 42
	10  Foundation                          0x35457747 __NSThreadPerformPerform + 350
	11  CoreFoundation                      0x35908ad3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
	12  CoreFoundation                      0x3590829f __CFRunLoopDoSources0 + 214
	13  CoreFoundation                      0x35907045 __CFRunLoopRun + 652
	14  CoreFoundation                      0x3588a4a5 CFRunLoopRunSpecific + 300
	15  CoreFoundation                      0x3588a36d CFRunLoopRunInMode + 104
	16  GraphicsServices                    0x37526439 GSEventRunModal + 136
	17  UIKit                               0x33396cd5 UIApplicationMain + 1080
	18  NxxMovie                          0x31b7 _mh_execute_header + 8631
	19  NxxMovie                          0x3150 _mh_execute_header + 8528
)

dSYM UUID: FF67F6D3-C71C-3A7D-9C4C-C4FFBF8EEEB9
CPU Type: armv7
Slide Address: 0x00001000
Binary Image: NxxMovie
Base Address: 0x000f4000
由于这类的崩溃信息通常难以重现, 没有任何的重现步骤,所以我们得找到发布该版本时的原始代码,可能会需要回朔到以前的SVN或者Git版本。

然后找到当时上传代码时使用的DYSM文件,这文件通常在.xcarchive文件中。 右键该文件, 然后通过Terminal工具cd到

cd /Users/heqin/Downloads/xxxMovie2.0.0_apps_0605_2104\ 13-6-5\ 下午9.02.xcarchive/dSYMs/xxxMovie.app.dSYM/Contents/Resources/DWARF

注意:1。对于成功生成archvie的项目, 在这个archive的包中, 是可以通过显示包内容, 看到DSYMs文件夹和一个products文件夹, 继续显示DSYMs文件夹下,可以看到一个xxx.app.DSYM文件,继续对它显示包内容,可以看到Contents/Resources/DWARF/xxxx文件, 这个文件是编译后的二进制文件,通过它可以进行反编译,从而找到二进制对应的源码位置。

2。 在xcode中,archive成功后, 会在Organizer界面中的Archives下, 可以看到所有的archive文件, 右键Show in Finder可以找到这个文件。


然后执行atos -arch armv7 -o xxxMovie 0x1153b9. 就可以看到这处内存地址反编译回来的源码行。

可以有效地帮助分析原因。


<think>好的,用户现在想了解如何通过last_kmsg分析设备重启前的内核崩溃原因。根据用户之前的问题和我的回答,我需要结合提供的引用内容来构建详细的步骤。首先,用户提到他们参考了四个引用,其中引用[1]讨论了设备关键服务崩溃导致重启的机制,引用[2]提到了通过dmesg和kmsg抓取日志的方法,引用[3]提到了内核崩溃转储分析器的作用,引用[4]则关于硬件模块的初始化。不过用户当前的问题主要集中在last_kmsg的使用上。 首先,我需要确认last_kmsg是什么。根据之前的回答,last_kmsg是保存在/proc/last_kmsg中的日志,记录了上一次内核崩溃的信息,前提是内核配置支持CONFIG_PSTORE。用户需要知道如何提取和分析这个文件。 接下来,用户可能需要具体的步骤,包括获取last_kmsg的权限要求、提取方法、以及如何解析其中的关键信息。根据引用[2],抓取dmesg和kmsg日志的方法可能类似,但last_kmsg需要特定的访问权限,可能需要root权限。 另外,引用[3]提到的崩溃转储分析器可能相关,但用户的问题更偏向于手动分析last_kmsg的内容。因此,我需要将步骤分解为提取日志、定位崩溃点(如Oops/Panic信息)、分析调用栈、寄存器状态,以及可能的工具辅助,如addr2line或gdb。 用户可能还需要了解常见错误类型,如空指针解引用、内存越界等,并如何根据日志中的信息定位代码位置。例如,引用[1]中的服务崩溃导致重启的情况,但这里更关注内核层面的崩溃,所以需要结合内核日志中的错误信息。 需要注意用户是否有足够的权限和正确的内核配置,因为如果设备不支持last_kmsg,用户可能需要其他方法。此外,引用[4]中的硬件模块初始化可能与某些驱动错误相关,但可能不在当前问题的范围内,不过可以作为可能的原因之一提及。 总结步骤应为:提取last_kmsg文件、过滤关键错误信息、解析调用栈和寄存器值、使用工具转换地址到代码行、结合代码和日志定位问题。同时,需要提醒用户权限和内核配置的问题,以及如何验证日志的完整性。</think>### 通过`last_kmsg`分析内核崩溃原因的完整步骤 --- #### 一、获取`last_kmsg`的前提条件 1. **内核配置支持** - 需启用崩溃日志持久化功能:`CONFIG_PSTORE=y`(确保内核编译时开启)[^3] 2. **访问权限** - 需要root权限访问`/proc/last_kmsg`文件 ```bash adb shell su -c "ls /proc/last_kmsg" # 验证文件存在性 ``` --- #### 二、关键操作步骤 **步骤1:提取崩溃日志** ```bash adb shell su -c "cat /proc/last_kmsg" > last_kmsg.log # 导出完整日志 ``` - **注意**:设备重启后需尽快提取,新内核启动可能覆盖旧日志[^1] **步骤2:定位崩溃触发点** ```bash grep -E "Panic|Oops|Call trace|BUG:" last_kmsg.log # 过滤关键标记 ``` **典型输出示例**: ```log [ 2.345678] Kernel panic - not syncing: Attempted to kill init! [ 2.345679] CPU: 0 PID: 1 Comm: init Tainted: G W 4.9.186 #1 [ 2.345680] Call trace: [ 2.345681] [<ffffffc0002085c4>] dump_backtrace+0x0/0x1a0 [ 2.345682] [<ffffffc0005f2a10>] panic+0x158/0x314 ``` **步骤3:分析调用栈(Call Trace)** - **符号解析**: 使用`addr2line`工具将地址转换为代码位置 ```bash arm-linux-androideabi-addr2line -e vmlinux ffffffc0002085c4 # 解析地址 ``` - **输出示例**: `drivers/char/example_driver.c:123` → 定位到具体驱动文件及行号 **步骤4:寄存器状态分析** 查找`PC is at`或`LR is at`字段: ```log [ 2.345683] PC is at faulty_function+0x1c/0x30 ``` - `+0x1c`表示指令偏移量,结合反汇编验证 ```bash arm-linux-androideabi-objdump -d vmlinux | grep "faulty_function" -A 20 ``` **步骤5:错误类型判定** | 错误特征 | 常见原因 | 解决方案 | |---------------------------|---------------------------|-----------------------------| | `NULL pointer dereference` | 空指针访问 | 检查指针初始化与判空逻辑 | | `general protection fault` | 内存越界或权限违规 | 使用KASAN检测内存错误 | | `scheduling while atomic` | 原子上下文中调用调度函数 | 替换为安全API(如工作队列) | --- #### 三、深度分析方法 1. **时间戳关联** - 对比崩溃时间与系统事件(如服务启动) ```log [ 4.567890] init: starting service 'example_service'... [ 4.567891] example_service: page allocation failure: order:4 [ 4.567892] Kernel panic - not syncing: Out of memory ``` → 服务内存申请触发OOM[^1] 2. **硬件状态验证** - 检查崩溃前硬件寄存器状态(如DMA控制器) ```log [ 1.234567] mmc0: DMA channel timeout, status=0x80000001 [ 1.234568] mmc0: error -110 whilst initialising SD card ``` → 需排查SD卡驱动或硬件连接 3. **并发问题检测** - 查找`spinlock`死锁或竞态条件 ```log [ 3.456789] BUG: spinlock lockup suspected on CPU#0 [ 3.456790] lock: 0xffffffc001234567, .magic: dead4ead, .owner: example_task/123 ``` → 使用`lockdep`工具验证锁顺序 --- #### 四、工具链配合 | 工具 | 用途 | 命令示例 | |-----------------|-------------------------------------------|-----------------------------------| | **addr2line** | 将地址转换为源码行号 | `addr2line -e vmlinux <address>` | | **objdump** | 反汇编定位指令级错误 | `objdump -d vmlinux > disasm.s` | | **gdb** | 动态调试内核符号 | `gdb vmlinux -ex "l *0x123456"` | | **pstore** | 持久化存储崩溃日志(需内核支持) | 查看`/sys/fs/pstore/`目录 | --- #### 五、调试案例演示 **场景**:设备因内存泄漏触发OOM Killer 1. **日志关键段** ```log [ 12.345678] Out of memory: Kill process 456 (example_daemon) score 789 [ 12.345679] Memory cgroup out of memory: Killed process 456 ``` 2. **关联分析** - 使用`kmemleak`检测未释放内存块 ```bash echo scan > /sys/kernel/debug/kmemleak # 触发内存泄漏扫描 cat /sys/kernel/debug/kmemleak # 查看泄漏点 ``` --- ### 注意事项 1. **日志完整性校验** - 检查日志结尾是否包含`---[ end Kernel panic - not syncing: ... ]---` 不完整日志可能因崩溃导致缓冲区未完全写入[^2] 2. **多崩溃场景区分** - 若设备频繁重启,需通过时间戳确认分析目标崩溃事件 ```bash grep "Boot completed" last_kmsg.log # 定位完整启动周期 ``` 3. **环境复现** - 对于偶发崩溃,建议启用`CONFIG_PANIC_TIMEOUT=5`强制保留崩溃现场 [^1]: 需root权限访问`/proc/last_kmsg` [^2]: 部分设备可能因硬件复位丢失最后若干条日志 [^3]: 崩溃转储分析依赖内核配置`CONFIG_PSTORE`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值