一次用户进程异常引起的kernel panic事后总结——高通平台,基于内存dump信息

本文分析了logcat服务导致的内存溢出问题,详细解释了logcat进程占用内存过大的原因,并探讨了如何从内存DUMP中获取logcat进程信息的方法。

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


Kernel log:

377.999271] Kernel panic - not syncing: Out of memory and no killableprocesses...


查看memory.txt



logcat进程占用内存太大,明显异常。

从内存DUMP中获得logcat进程信息,虽然很是繁琐,但写程序搞定,就当调BUG了。


查看logcat服务:

service apk_logfs /system/bin/logcat -b system -b events -b main -b radio -b crash -v threadtime -f /data/misc/logd/aplogs -r 10240 -n 512 
class main 
# disabled 
user root 
seclabel u:r:apk_logfs:s0 

通过其他方式查看/data/misc/logd/aplogs大小,3GB+,结合调用栈ReadFdToString,一个3GB+的文件想一次装入内存,确实会引起内存不足。
并且我分析调用栈的时候,发现很多lib代码段(包括logcat本身)都已经不在内存中了,说明kernel为了这个加载已经很努力了。
当然,后续分析aplogs太大,分割失败,主要是logcat 关于unlink的avc权限不足就不是我这边分析的了。



<think>我们面对的问题是如何在MTK平台上定位导致kernelpanic的具体代码行。根据提供的引用资料,我们可以总结出以下步骤: 1. **获取kernelpanic时的关键信息**:当发生kernelpanic时,系统会输出关键信息,包括PC指针(程序计数器)的值,该值指示了导致panic的指令地址。例如,引用[2]中显示PC指针停留在`ffffff8008474b88`。 2. **使用addr2line工具定位代码行**:通过addr2line工具,结合内核的符号映射表(vmlinux),可以将PC指针的地址转换为具体的文件名和行号。命令格式如下:```basharm-linux-androideabi-addr2line-evmlinux-f-C<address>```其中:-`-e vmlinux`:指定内核镜像文件(包含符号表)。- `-f`:显示函数名。-`-C`:对C++符号进行demangle(也适用于C代码中的函数名)。-`<address>`:PC指针的值(例如`ffffff8008474b88`)。注意:需要根据目标平台使用对应的工具链前缀(如`arm-linux-androideabi-`、`aarch64-linux-gnu-`等)。 3. **确保内核配置支持**:在编译内核时,需要开启`KALLSYMS`选项(引用[3]),以便在vmlinux中包含所有符号信息。配置路径:`Generalsetup -->Configure standardkernel features--> Loadall symbolsfor debugging/ksymoops`。 4. **利用pstore保存panic信息(可选)**:如果系统在panic后重启,可以通过配置pstore(引用[4])将panic信息保存到RAM或块设备中,以便重启后读取。配置路径:-`Filesystems -->Miscellaneous filesystems -->Persistent storesupport`-勾选`Log panic/oopsto aRAM buffer`(pstore/ram)或`Log panic/oopsto ablock device`(pstore/blk)。 5. **分析kernellog**:从dmesg或系统日志中提取panic信息,包括PC指针值、调用栈等。引用[5]展示了使用addr2line分析dhd_debug.o模块的例子,但注意对于内核本身,我们使用vmlinux。 **具体步骤**:1.**获取vmlinux文件**:该文件位于内核编译输出目录(如`out/target/product/$project/obj/KERNEL_OBJ/vmlinux`)。 2. **从kernellog中提取PC指针地址**:查找类似以下信息:```[<ffffff8008474b88>] (regulator_is_enabled)from [<ffffff8008474c00>](...)```其中`ffffff8008474b88`就是我们需要定位的地址。 3. **运行addr2line命令**:```bashaarch64-linux-gnu-addr2line -e path/to/vmlinux-f-Cffffff8008474b88```输出将包括函数名和文件名:行号。4.**分析结果**:根据输出的文件名和行号,查看对应代码,分析panic原因。**注意事项**:-确保使用的vmlinux文件与发生panic的内核版本完全一致。-如果panic发生在内核模块中,需要对应的模块文件(如`.ko`)及其编译生成的调试信息(如`.o`文件),如引用[5]所示。**示例**:假设在kernel log中看到: ```[<ffffff8008474b88>] regulator_is_enabled+0x0/0x20``` 运行命令: ```bashaarch64-linux-gnu-addr2line -e vmlinux-f-Cffffff8008474b88```输出:``` regulator_is_enableddrivers/regulator/core.c:1234``` 则panic发生在`drivers/regulator/core.c`文件的第1234行。通过以上步骤,即可在MTK平台上定位导致kernelpanic的具体代码行。</think>### 在MTK平台定位Kernel Panic代码行的完整指南 #### 一、关键步骤分析 1. **获取PC指针地址** 发生Kernel Panic时,首先从日志中提取程序计数器(PC)地址。例如引用[2]中的案例: > `PC指针停留在regulator_is_enabled函数ffffff8008474b88` *关键日志特征示例:* `[<ffffff8008474b88>] (regulator_is_enabled+0x0/0x20)` 2. **准备符号文件** - 确保编译内核时开启符号支持(引用[3]): ```text General setup → Configure standard kernel features → [*] Load all symbols for debugging/ksymoops ``` - 获取与崩溃内核匹配的`vmlinux`文件(位于`out/target/product/$project/obj/KERNEL_OBJ/`) 3. **使用addr2line定位代码行**(引用[2][5]) ```bash # ARM64平台命令格式 aarch64-linux-gnu-addr2line -e vmlinux -f -C <PC地址> # 示例(地址替换为实际值) aarch64-linux-gnu-addr2line -e vmlinux -f -C ffffff8008474b88 ``` *输出示例:* `regulator_is_enabled` `drivers/regulator/core.c:1234` 4. **配置pstore持久化日志**(引用[4]) 当系统重启后日志丢失时,需在内核配置中启用: ```text File systems → [*] Persistent store support → [*] Log panic/oops to a RAM buffer # RAM方案 [*] Log panic/oops to a block device # eMMC方案 ``` #### 二、MTK平台特殊处理 1. **获取完整日志** 使用MTK专属工具`MTKLogger`或`/proc/last_kmsg`: ```bash adb shell cat /proc/last_kmsg > panic.log ``` 2. **处理地址偏移** MTK内核通常启用KASLR,需从日志提取随机偏移: ```text Kernel Offset: 0x1a8c0000 from 0xffffff8008000000 ``` 计算实际地址: $$ \text{实际地址} = \text{PC值} - 0\text{x}1\text{a}8\text{c}0000 $$ 3. **模块符号定位** 若崩溃发生在驱动模块(如`dhd.ko`),使用模块的`.o`文件(引用[5]): ```bash arm-linux-androideabi-addr2line -e dhd_debug.o -f -C 0x2ac ``` #### 三、典型错误排查 1. **地址无效** → 检查KASLR偏移计算 2. **无符号信息** → 确认`CONFIG_DEBUG_INFO=y` 3. **版本不匹配** → 核对内核版本号: `adb shell cat /proc/version` #### 四、自动化调试方案 ```bash #!/bin/bash # MTK_kpanic_debug.sh PC_ADDR=$(grep "PC :" panic.log | awk '{print $NF}') OFFSET=$(grep "Kernel Offset:" panic.log | cut -d':' -f2) REAL_ADDR=$(printf "0x%x" $(( $PC_ADDR - $OFFSET )) ) aarch64-linux-gnu-addr2line -e vmlinux $REAL_ADDR ``` > **注意事项**: > - 确保工具链与内核架构匹配(ARM32/ARM64) > - 优先使用`pstore`保存日志(引用[4]) > - 对于eMMC写入问题,需检查MTK存储驱动兼容性(引用[4])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值