Linux核心除錯之dump stack的簡單使用

2021-09-24 19:26:27 字數 1986 閱讀 6056

剛剛接觸核心,在除錯過程中用printk列印資訊當然是直接有效的辦法,但當我們不知到乙個函式或者乙個模組到底在**出了問題時我們可以利用dump_stack有效的找到問題的根源,下面只是簡單的給出了使用方法。

下面是使用例子

makefile檔案

obj-m := hello.o

kernelbuild :=/lib/modules/$(shell uname -r)/build

default: 

make -c $(kernelbuild) m=$(shell pwd) modules 

clean: 

rm -rf *.o *.ko *.mod.c *.cmd *.markers *.order *.symvers *.tmp_versions

hello.c檔案

#include

#include

#include

#include

module_license("dual bsd/gpl");

static int __init hello_init(void)

static void __exit hello_exit(void)

module_init(hello_init);

module_exit(hello_exit);

注意:使用dump_stack()要加上這兩個標頭檔案

#include 

#include 

然後make得到hello.ko

在執行insmod hello.ko把模組插入核心

執行檢視核心啟動資訊的阿命令 dmesg

[  452.785164] dump_stack start

[  452.785177] pid: 1874, comm: insmod tainted: g           o 3.8.6 #2

[  452.785179] call trace:

[  452.785185]   hello_init+0x17/0x27 [hello]

[  452.785218]   do_one_initcall+0x34/0x170

[  452.785233]   do_init_module+0x3c/0x1a0

[  452.785237]   load_module+0x1551/0x15f0

[  452.785243]   sys_init_module+0x9b/0xb0

[  452.785266]   sysenter_do_call+0x12/0x28

[  452.785267] dump_stack over

上面打出執行這個模組時呼叫的函式

刪除模rmmod hello

但是,使用dump_stack有不足之處

dump_stack的原理是遍歷堆疊,把所有可能是核心函式的內容找出來,並列印對應的函式。因為函式呼叫時會把下一條指令的位址放到堆疊中。所以只要找到這些return address,就可以找到這些return address所在函式,進而列印函式的呼叫關係。

使用dump_stack可能不準確,可能的原因有三: 

1.所有這些可以找到的函式位址,存在/proc/kallsyms中。它並不包括核心中所有的函式,而只包括核心中stext~etext和sinittext~einittext範圍的函式,及模組中的函式。詳細可參考scripts/kallsyms.c 

2.一些函式在編譯時進行了優化,把call指令優化為jmp指令,這樣在呼叫時就不會把return address放到堆疊,導致dump_stack時在堆疊中找不到對應的資訊。 

3.堆疊中可能有一些數值,它們不是return address,但是在核心函式位址的範圍裡,這些數值會被誤認為return address從而列印出錯誤的呼叫關係。

對於呼叫關係比較複雜的函式,在目標函式裡面呼叫dump_stack()可以檢視目標函式的呼叫鏈

但是如果情況更複雜,涉及到很多函式指標的傳遞和鉤子函式,那麼dump_stack的作用也是有限

linux 核心除錯

debug.hacks 一書中,介紹了如果除錯核心問題,在第五章的 實踐核心除錯 總體來說,有一下的方法來除錯核心 1.用kgdb單步除錯。具體請參見 2.加列印printk來定位。3.根據核心出錯的kernel panic oops資訊,反彙編,定位問題 4.編寫復現程式,或者創造復現條件。5.g...

LINUX核心設計與實現之除錯

核心排程主要靠經驗和對整個作業系統的把握.18.1 排程前需要準備什麼 重現bug.18.2 核心中的 bug 引發核心中的bug 的原因如下 同步 定時限制 競爭條件.18.3 printk 在終端沒有初始化之前,printk 函式是不可用的 比如在 setup arch 函式之前 不過可以用 p...

Linux核心除錯方法總結之sysrq

sysrq 用途 sysrq被稱為 魔術組合鍵 是內置於linux核心的除錯工具。只要核心沒有完全鎖住,不管核心在做什麼事情,使用這些組合鍵都可以蒐集包括系統記憶體使用 cpu任務處理 程序執行狀態等系統執行資訊。原理 核心幫助文件kernel documentation sysrq.txt 首先,...