在嵌入式系統(tǒng)(如基于瑞芯微RK3399的Android設(shè)備)開(kāi)發(fā)或維護(hù)中,系統(tǒng)常因內(nèi)核崩潰(Panic)、用戶空間異常等突發(fā)情況重啟,導(dǎo)致關(guān)鍵日志丟失。此時(shí),Last Log(依托Linux內(nèi)核的ramoops機(jī)制實(shí)現(xiàn))可在系統(tǒng)異常時(shí)保存核心日志,為事后故障分析提供關(guān)鍵依據(jù)。本文將詳細(xì)介紹其配置方法與問(wèn)題排查實(shí)踐,并通過(guò)具體案例演示實(shí)戰(zhàn)流程。

一、Last Log的核心:Ramoops機(jī)制
ramoops是Linux內(nèi)核的一項(xiàng)功能——它會(huì)預(yù)留一段固定內(nèi)存區(qū)域,當(dāng)系統(tǒng)發(fā)生異常(如內(nèi)核Panic、意外重啟)時(shí),自動(dòng)將關(guān)鍵日志(內(nèi)核日志、用戶空間日志、函數(shù)追蹤等)寫(xiě)入該區(qū)域。由于這段內(nèi)存的特殊性,系統(tǒng)重啟后數(shù)據(jù)不會(huì)丟失,可通過(guò)/sys/fs/pstore目錄訪問(wèn)這些“遺留日志”,進(jìn)而分析故障根因。
二、配置Ramoops,啟用Last Log
要啟用Last Log,需在**設(shè)備樹(shù)(DTS)**中添加ramoops相關(guān)節(jié)點(diǎn),為其分配內(nèi)存并定義日志參數(shù)。
2.1設(shè)備樹(shù)節(jié)點(diǎn)添加
在設(shè)備樹(shù)源文件(.dts)中,添加以下兩個(gè)節(jié)點(diǎn)(需根據(jù)硬件內(nèi)存布局調(diào)整參數(shù)):
ramoops_mem: ramoops_mem {reg = <0x00x1100000x00xf0000>; /* 預(yù)留內(nèi)存的起始地址與大小 */reg-names ="ramoops_mem"; /* 內(nèi)存區(qū)域命名,供后續(xù)引用 */};ramoops {compatible ="ramoops"; /* 與內(nèi)核ramoops驅(qū)動(dòng)兼容 */record-size = <0x00x20000>; /* 單個(gè)日志記錄的大小 */console-size = <0x00x80000>; /* 內(nèi)核控制臺(tái)日志(last_log)的空間 */ftrace-size = <0x00x00000>; /* 函數(shù)追蹤(ftrace)日志的空間 */pmsg-size = <0x00x50000>; /* 用戶空間日志(如Android logcat)的空間 */memory-region = <&ramoops_mem>; /* 引用上面定義的內(nèi)存區(qū)域 */};
2.2節(jié)點(diǎn)參數(shù)詳解
?ramoops_mem節(jié)點(diǎn):負(fù)責(zé)定義預(yù)留內(nèi)存區(qū)域。
?reg = <起始地址 地址長(zhǎng)度...>:指定內(nèi)存的起始地址與大?。ㄐ璐_保該區(qū)域不與其他模塊內(nèi)存沖突)。
?reg-names = "ramoops_mem":為內(nèi)存區(qū)域命名,方便ramoops節(jié)點(diǎn)引用。
?ramoops節(jié)點(diǎn):負(fù)責(zé)配置ramoops的行為。
?compatible = "ramoops":聲明與內(nèi)核ramoops驅(qū)動(dòng)兼容,確保驅(qū)動(dòng)能識(shí)別并使用該節(jié)點(diǎn)。
?record-size/console-size/ftrace-size/pmsg-size:分別指定“單條日志”“內(nèi)核控制臺(tái)日志”“函數(shù)追蹤日志”“用戶空間日志”的預(yù)留空間大小。
?memory-region = <&ramoops_mem>:指定日志存儲(chǔ)的目標(biāo)內(nèi)存區(qū)域(即前面定義的ramoops_mem)。
三、查看與解析Last Log
系統(tǒng)重啟后,可通過(guò)/sys/fs/pstore目錄訪問(wèn)Last Log文件。不同文件對(duì)應(yīng)不同類(lèi)型的日志,需結(jié)合場(chǎng)景選擇查看。
3.1訪問(wèn)日志文件
通過(guò)命令行進(jìn)入/sys/fs/pstore目錄,列出所有日志文件:
cd/sys/fs/pstorels
以RK3399設(shè)備為例,通常會(huì)看到以下文件(不同場(chǎng)景下文件存在性不同):
?dmesg-ramoops-0:內(nèi)核Panic后保存的日志,記錄內(nèi)核崩潰前的關(guān)鍵調(diào)用棧、錯(cuò)誤信息。
?pmsg-ramoops-0:用戶空間日志(如Android系統(tǒng)的logcat日志),記錄應(yīng)用、系統(tǒng)服務(wù)的運(yùn)行信息。
?ftrace-ramoops-0:函數(shù)追蹤(ftrace)日志,記錄指定時(shí)間段內(nèi)的函數(shù)調(diào)用流程,用于性能分析。
?console-ramoops-0:上次啟動(dòng)的內(nèi)核日志(last_log),但僅保存優(yōu)先級(jí)高于默認(rèn)日志級(jí)別的日志。
3.2日志查看命令
根據(jù)日志類(lèi)型,使用不同命令查看內(nèi)容:
?查看內(nèi)核Panic日志:
catdmesg-ramoops-0
?查看上次內(nèi)核高優(yōu)先級(jí)日志(last_log):
catconsole-ramoops-0
?解析用戶空間日志(如Android logcat):
logcat-L pmsg-ramoops-0
(通過(guò)logcat工具解析后,日志格式更符合Android開(kāi)發(fā)習(xí)慣)
?查看函數(shù)追蹤日志:
catftrace-ramoops-0
四、實(shí)戰(zhàn):用Last Log排查典型問(wèn)題(含具體案例)
以下通過(guò)內(nèi)核空指針、Android應(yīng)用ANR、驅(qū)動(dòng)初始化失敗三個(gè)典型場(chǎng)景,演示Last Log的排查流程。
案例1:內(nèi)核空指針解引用導(dǎo)致系統(tǒng)Panic重啟
現(xiàn)象:設(shè)備運(yùn)行過(guò)程中突然黑屏重啟,無(wú)明顯操作觸發(fā)。
排查步驟:
1.系統(tǒng)重啟后,進(jìn)入/sys/fs/pstore目錄,查看內(nèi)核Panic日志:
catdmesg-ramoops-0
1.日志關(guān)鍵內(nèi)容(示例):
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明確存在空指針解引用問(wèn)題;Call trace的堆棧追蹤顯示,故障源于problematic_driver模塊的problematic_driver_function函數(shù)。由此可定位到該驅(qū)動(dòng)存在“未正確初始化指針就解引用”的代碼邏輯問(wèn)題,需修改驅(qū)動(dòng)代碼(如增加指針有效性檢查)并重新測(cè)試。
案例2:Android應(yīng)用頻繁ANR(應(yīng)用無(wú)響應(yīng))
現(xiàn)象:某社交應(yīng)用打開(kāi)后幾秒內(nèi)提示“應(yīng)用無(wú)響應(yīng)”,強(qiáng)制關(guān)閉后再次打開(kāi)仍異常。
排查步驟:
1.應(yīng)用觸發(fā)ANR后,進(jìn)入/sys/fs/pstore目錄,解析用戶空間日志:
logcat-L pmsg-ramoops-0
1.日志關(guān)鍵內(nèi)容(示例):
09-2214:30:00.12312345678E AndroidRuntime: FATAL EXCEPTION: main09-2214:30:00.12312345678E AndroidRuntime: Process: com.example.social, PID:123409-2214:30:00.12312345678E AndroidRuntime: java.lang.RuntimeException: ANR in com.example.social...09-2214:30:00.12312345678E AndroidRuntime: Caused by: android.os.DeadlineExceededException: Main thread idle timeout of5seconds expired...09-2214:30:00.12312345678E AndroidRuntime: at com.example.social.MainActivity.loadLargeImageSync(MainActivity.java:123)
1.分析:日志中ANR與DeadlineExceededException表明“主線程因耗時(shí)操作被阻塞”;調(diào)用棧顯示,MainActivity的loadLargeImageSync方法(同步加載大圖片)導(dǎo)致主線程卡頓超過(guò)5秒。需將該方法改為異步加載(如使用AsyncTask或線程池),避免主線程被長(zhǎng)時(shí)間占用。
案例3:設(shè)備啟動(dòng)卡在logo界面,驅(qū)動(dòng)初始化失敗
現(xiàn)象:設(shè)備上電后,屏幕一直停留在廠商logo界面,無(wú)法進(jìn)入系統(tǒng)。
排查步驟:
1.強(qiáng)制重啟設(shè)備(或等待自動(dòng)重啟)后,進(jìn)入/sys/fs/pstore目錄,查看高優(yōu)先級(jí)內(nèi)核日志:
catconsole-ramoops-0
1.日志關(guān)鍵內(nèi)容(示例):
[ 2.345678] problematic_driver: probe of1-001a failed witherror-110[ 2.345789] platform12340000.device: Driver problematic_driver failed to probe[ 2.345890] Kernelpanic- not syncing: Essential driver failed to initialize
1.分析:日志中probe of 1-001a failed with error -110表明problematic_driver在探測(cè)硬件設(shè)備(I2C地址1-001a)時(shí)失?。ㄥe(cuò)誤碼-110對(duì)應(yīng)“操作超時(shí)”);且該驅(qū)動(dòng)屬于“核心驅(qū)動(dòng)”,直接導(dǎo)致內(nèi)核Panic。需檢查兩方面:
?硬件層面:確認(rèn)I2C設(shè)備是否存在、供電是否正常、硬件連線是否松動(dòng);
?驅(qū)動(dòng)層面:修改驅(qū)動(dòng)的“探測(cè)超時(shí)時(shí)間”,或增加硬件存在性檢測(cè)邏輯。
五、總結(jié)
通過(guò)配置ramoops啟用Last Log,能在系統(tǒng)異常時(shí)“留存”關(guān)鍵日志,為嵌入式系統(tǒng)(尤其是無(wú)持久化日志存儲(chǔ)的場(chǎng)景)的問(wèn)題排查提供有力支持。結(jié)合/sys/fs/pstore下的不同日志文件,可覆蓋內(nèi)核Panic、用戶空間異常、性能追蹤、啟動(dòng)故障等多個(gè)維度的分析;再通過(guò)“現(xiàn)象-操作-日志分析-根因定位”的實(shí)戰(zhàn)流程,能高效解決各類(lèi)系統(tǒng)問(wèn)題,是提升系統(tǒng)穩(wěn)定性的核心調(diào)試工具。
-
嵌入式系統(tǒng)
+關(guān)注
關(guān)注
41文章
3831瀏覽量
133909 -
內(nèi)核
+關(guān)注
關(guān)注
4文章
1476瀏覽量
43098 -
瑞芯微
+關(guān)注
關(guān)注
27文章
861瀏覽量
54678
發(fā)布評(píng)論請(qǐng)先 登錄
恩智浦解讀Zephyr log系統(tǒng)的使用 Zephyr的shell和log功能介紹
全棧開(kāi)發(fā)進(jìn)階指南:LuatOS-log庫(kù)從入門(mén)到實(shí)戰(zhàn)!
機(jī)器學(xué)習(xí)實(shí)踐指南——案例應(yīng)用解析
Flink on YARN(下):常見(jiàn)問(wèn)題與排查思路
Flink on YARN(下):常見(jiàn)問(wèn)題與排查思路
談一談Firefly Android系統(tǒng)的功能
分享幾種RK3399開(kāi)啟ramoops查看kernel log的方法
自動(dòng)化測(cè)試系統(tǒng)的最佳實(shí)踐指南秘籍
嵌入式系統(tǒng)log模塊設(shè)計(jì)
Linux主機(jī)排查腳本介紹
嵌入式Linux上使用Ramoops的代碼應(yīng)用
利用Last Log(Ramoops)排查系統(tǒng)問(wèn)題:配置與實(shí)踐指南
評(píng)論