利用Last Log(Ramoops)排查系统问题:配置与实践指南

电子说

1.4w人已加入

描述

 

 

在嵌入式系统(如基于瑞芯微 RK3399 的 Android 设备)开发或维护中,系统常因内核崩溃(Panic)、用户空间异常等突发情况重启,导致关键日志丢失。此时,Last Log(依托 Linux 内核的ramoops机制实现)可在系统异常时保存核心日志,为事后故障分析提供关键依据。本文将详细介绍其配置方法与问题排查实践,并通过具体案例演示实战流程。

内核

一、Last Log 的核心:Ramoops 机制

 

ramoops Linux 内核的一项功能 —— 它会预留一段固定内存区域,当系统发生异常(如内核 Panic、意外重启)时,自动将关键日志(内核日志、用户空间日志、函数追踪等)写入该区域。由于这段内存的特殊性,系统重启后数据不会丢失,可通过/sys/fs/pstore目录访问这些遗留日志,进而分析故障根因。

 

 

二、配置 Ramoops,启用 Last Log

 

要启用 Last Log,需在 ** 设备树(DTS** 中添加ramoops相关节点,为其分配内存并定义日志参数。

 

 

2.1 设备树节点添加

 

在设备树源文件(.dts)中,添加以下两个节点(需根据硬件内存布局调整参数):

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
ramoops_mem: ramoops_mem {    reg = <0x0 0x110000 0x0 0xf0000>;  /* 预留内存的起始地址与大小 */    reg-names = "ramoops_mem";         /* 内存区域命名,供后续引用 */};ramoops {    compatible = "ramoops";            /* 与内核ramoops驱动兼容 */    record-size = <0x0 0x20000>;       /* 单个日志记录的大小 */    console-size = <0x0 0x80000>;      /* 内核控制台日志(last_log)的空间 */    ftrace-size = <0x0 0x00000>;       /* 函数追踪(ftrace)日志的空间 */    pmsg-size = <0x0 0x50000>;         /* 用户空间日志(如Android logcat)的空间 */    memory-region = <&ramoops_mem>;    /* 引用上面定义的内存区域 */};

2.2 节点参数详解

 

ramoops_mem节点:负责定义预留内存区域

 

 

reg = <起始地址 地址长度 ...>:指定内存的起始地址与大小(需确保该区域不与其他模块内存冲突)。

 

 

reg-names = "ramoops_mem":为内存区域命名,方便ramoops节点引用。

 

 

ramoops节点:负责配置ramoops的行为。

 

 

compatible = "ramoops":声明与内核ramoops驱动兼容,确保驱动能识别并使用该节点。

 

 

record-size/console-size/ftrace-size/pmsg-size:分别指定单条日志”“内核控制台日志”“函数追踪日志”“用户空间日志” 的预留空间大小。

 

 

memory-region = <&ramoops_mem>:指定日志存储的目标内存区域(即前面定义的ramoops_mem)。

 

 

三、查看与解析 Last Log

 

系统重启后,可通过/sys/fs/pstore目录访问 Last Log 文件。不同文件对应不同类型的日志,需结合场景选择查看。

 

 

3.1 访问日志文件

 

通过命令行进入/sys/fs/pstore目录,列出所有日志文件:

 

 

  •  
  •  
cd /sys/fs/pstorels

 RK3399 设备为例,通常会看到以下文件(不同场景下文件存在性不同):

 

 

dmesg-ramoops-0内核 Panic 后保存的日志,记录内核崩溃前的关键调用栈、错误信息。

 

 

pmsg-ramoops-0用户空间日志(如 Android 系统的 logcat 日志),记录应用、系统服务的运行信息。

 

 

ftrace-ramoops-0函数追踪(ftrace)日志,记录指定时间段内的函数调用流程,用于性能分析。

 

 

console-ramoops-0上次启动的内核日志(last_log,但仅保存优先级高于默认日志级别的日志。

 

 

3.2 日志查看命令

 

根据日志类型,使用不同命令查看内容:

 

 

查看内核 Panic 日志

 

 

  •  
cat dmesg-ramoops-0

查看上次内核高优先级日志(last_log

 

 

  •  
cat console-ramoops-0

解析用户空间日志(如 Android logcat

 

 

  •  
logcat -L pmsg-ramoops-0

(通过logcat工具解析后,日志格式更符合 Android 开发习惯)

 

 

查看函数追踪日志

 

 

  •  
cat ftrace-ramoops-0

四、实战:用 Last Log 排查典型问题(含具体案例)

 

以下通过内核空指针、Android 应用 ANR、驱动初始化失败三个典型场景,演示 Last Log 的排查流程。

 

 

案例 1:内核空指针解引用导致系统 Panic 重启

 

现象:设备运行过程中突然黑屏重启,无明显操作触发。

 

 

排查步骤

 

 

1.系统重启后,进入/sys/fs/pstore目录,查看内核 Panic 日志:

 

 

  •  
cat dmesg-ramoops-0

1.日志关键内容(示例):

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
Kernel panic - not syncing: Null pointer dereferenceCPU: 0 PID: 1234 Comm: problem_process Tainted: G        W  ... Call trace:[<ffffffc0002a3450>] dump_backtrace+0x0/0x180[<ffffffc0002a3830>] show_stack+0x10/0x20[<ffffffc000a55080>] dump_stack+0xd8/0x134[<ffffffc0002f4f2c>] panic+0x18c/0x334[<ffffffc0000a2b50>] __do_page_fault+0x3a0/0x480...[<ffffffc0008b1234>] problematic_driver_function+0x20/0x80 [problematic_driver]

1.分析:日志中Null pointer dereference明确存在空指针解引用问题;Call trace的堆栈追踪显示,故障源于problematic_driver模块的problematic_driver_function函数。由此可定位到该驱动存在未正确初始化指针就解引用” 的代码逻辑问题,需修改驱动代码(如增加指针有效性检查)并重新测试。

 

 

案例 2Android 应用频繁 ANR(应用无响应)

 

现象:某社交应用打开后几秒内提示应用无响应,强制关闭后再次打开仍异常。

 

 

排查步骤

 

 

1.应用触发 ANR 后,进入/sys/fs/pstore目录,解析用户空间日志:

 

 

  •  
logcat -L pmsg-ramoops-0

1.日志关键内容(示例):

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
09-22 14:30:00.123  1234  5678 E AndroidRuntime: FATAL EXCEPTION: main09-22 14:30:00.123  1234  5678 E AndroidRuntime: Process: com.example.social, PID: 123409-22 14:30:00.123  1234  5678 E AndroidRuntime: java.lang.RuntimeException: ANR in com.example.social...09-22 14:30:00.123  1234  5678 E AndroidRuntime: Caused by: android.os.DeadlineExceededException: Main thread idle timeout of 5 seconds expired...09-22 14:30:00.123  1234  5678 E AndroidRuntime: at com.example.social.MainActivity.loadLargeImageSync(MainActivity.java:123)

1.分析:日志中ANRDeadlineExceededException表明主线程因耗时操作被阻塞;调用栈显示,MainActivityloadLargeImageSync方法(同步加载大图片)导致主线程卡顿超过 5 秒。需将该方法改为异步加载(如使用AsyncTask或线程池),避免主线程被长时间占用。

 

 

案例 3:设备启动卡在 logo 界面,驱动初始化失败

 

现象:设备上电后,屏幕一直停留在厂商 logo 界面,无法进入系统。

 

 

排查步骤

 

 

1.强制重启设备(或等待自动重启)后,进入/sys/fs/pstore目录,查看高优先级内核日志:

 

 

  •  
cat console-ramoops-0

1.日志关键内容(示例):

 

 

  •  
  •  
  •  
[    2.345678] problematic_driver: probe of 1-001a failed with error -110[    2.345789] platform 12340000.device: Driver problematic_driver failed to probe[    2.345890] Kernel panic - not syncing: Essential driver failed to initialize

1.分析:日志中probe of 1-001a failed with error -110表明problematic_driver在探测硬件设备(I2C 地址1-001a)时失败(错误码-110对应操作超时);且该驱动属于 核心驱动,直接导致内核 Panic。需检查两方面:

 

 

硬件层面:确认 I2C 设备是否存在、供电是否正常、硬件连线是否松动;

 

 

驱动层面:修改驱动的探测超时时间,或增加硬件存在性检测逻辑。

 

 

五、总结

 

通过配置ramoops启用 Last Log,能在系统异常时 留存” 关键日志,为嵌入式系统(尤其是无持久化日志存储的场景)的问题排查提供有力支持。结合/sys/fs/pstore下的不同日志文件,可覆盖内核 Panic、用户空间异常、性能追踪、启动故障等多个维度的分析;再通过现象 操作 日志分析 根因定位” 的实战流程,能高效解决各类系统问题,是提升系统稳定性的核心调试工具。

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分