轉自:https://blog.csdn.net/wenjin359/article/details/82694579
1、early printk loglevel
printk的log輸出是由console實現(會在其他文章中說明)。由於在kernel剛啟動的過程中,還沒有為串口等設備等注冊console(在device probe階段實現),此時無法通過正常的console來輸出log。
為此,linux提供了early console機制,用於實現為設備注冊console之前的早期log的輸出。這個console在kernel啟動的早期階段就會被注冊,主要通過輸出設備(比如串口設備)的簡單的write方法直接進行數據打印。
CONFIG_DEBUG_LL
ENTRY(printch)定義在arch/arm/debug.S中,需要用這個宏來打開。
CONFIG_EARLY_PRINTK
lichee\linux-3.10\arch\arm64\kernel\early_printk.c
2、initcall_debug
initcall_debug參數定位初始化過程中的錯誤信息發生的位置。
3、內核打印
Linux內核用函數printk打印調試信息,該函數的用法與C庫打印函數printf格式類似,但在內核使用。用戶可在內核代碼中的某位置加入函數printk,直接把所關心的信息打打印到屏幕上或日志文件中。
函數printk根據日志級別(loglevel)對調試信息進行分類。日志級別用宏定義,展開為一個字符串,在編譯時由預處理器將它和消息文本拼接成一個字符串。
(1)、不直接調用printk,而是調用pr_xxx,如下
(2)、不直接調用printk,而是調用dev_xxx
設備的名字將為打印前綴, dev_warn(); dev_info(); dev_emerg();
(3)、帶函數與行數打印
printk("%s%d\n", __func__, __LINE__);
(4)、printk
printk打印級別動態調整
printk有8個loglevel,定義在lichee\linux-3.10\include\linux\ kern_levels.h中,其中數值范圍從0到7,數值越小,優先級越低。未指定優先級的默認級別定義在/kernel/printk.c中,當優先級的值小console_loglevel這個整數變量的值,信息才能顯示出來
printk在中斷,軟中斷,spinlock里面都可以調用。printk的開銷很大,尤其是串口打印,會讓系統慢很多,所以產品里面減少不必要的打印,或者bootargs里面"quiet"。
(5)、內核帶時間戳打印
(6)、dumpstack() warn_on(1)
回溯函數調用過程。
4、內核模塊源碼級調試
比較少用,參考kdb,gdb調試文檔(待續,本人只用gdb調試過上層,沒有調過內核,視頻里面看也只是泛泛而講)。
5、oops與panic
Oops英文單詞的中文含義是“哎呀”,表示“驚嘆”;Panic英文單詞的中文含義是“驚慌”。所以panic的程度顯然是高於oops的,因為驚嘆不一定會驚慌,而驚慌最容易失措,內核panic后,就死機了,俗稱內核崩潰。但是內核報oops,這個時候不見得會panic,它可能只是報個oops,殺死進程而已。
oops不一定panic,中斷上下文的oops會panic,如果panic_on_oops設置為1,一律panic。
oops 顯示發生錯誤時處理器的狀態,包括 CPU 寄存器的內容、頁描述符表的位置,以及其他一些信息。
--->cd0+a0=d70
6、其他內核debug選項和功能
(1)、 no_console_suspend
在suspend的時候console 不進行suspend,否則console suspend之后其他driver在suspend 過程中印的log都顯示不出來,因此加這個參數一般用於調試suspend 和 resume。在bootargs中添加"no_console_suspend"參數。
(2)、SLUB_DEBUG kmemleak --->內存檢測
Linux常見的內存訪問錯誤有:越界訪問(out of bounds)、訪問已經釋放的內存(use after free)、重復釋放、內存泄露(memory leak)、棧溢出(stack overflow)等。
(a)、SLUB_DEBUG 內核中小塊內存大量使用slab/slub分配器,slub_debug提供了:訪問已經釋放的內存、越界訪問、重復釋放內存等功能檢測。
支持slub_debug內核配置
重新配置kernel選項,打開如下選項即可。
CONFIG_SLUB=y
CONFIG_SLUB_DEBUG=y
CONFIG_SLUB_DEBUG_ON=y
(1)、重復釋放
2c4+10c -> 3D0
(2)、內存越界
(b)、kmemleak是內核提供的一種檢測內存泄露工具,啟動一個內核線程掃描內存,並打印發現新的未引用對象數量。
使用kmemlieak,需要打開如下內核選項。
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=400
# CONFIG_DEBUG_KMEMLEAK_TEST is not set
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y---------或者關閉此選項,則不需要在命令行添加kmemleak=on。
(3)、DEBUG_ATOMIC_SLEEP -->檢測在spinlock,中斷,軟中斷中的sleep
(4)、RCU Stall
內核配置項:
(5)、Lockup detector
kernel/watchdog.c
NMI中斷+定時器中斷+高優先級RT線程
用定時器中斷,檢測高優先級線程有無機會執行->softlockup
用NMI,檢測定時器中斷有無機會執行->hard lockup
內核選項:
示例:
————————————————
版權聲明:本文為CSDN博主「Andy_0755」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/wenjin359/article/details/82694579