核心模組宕機除錯

2021-06-01 19:51:26 字數 1128 閱讀 6531

介紹一種核心模組宕機除錯的方法。在程式中,通常必現的宕機很好解決,但是如果是拷機宕機的話,則如果有好的方法和工具借助往往會極大的提高解決問題的速度。在linux中,應用空間程式宕機通常可以借助gdb、addr2line等工具進行快速定位。但是,在核心空間中,大部分嵌入式晶元都不支援核心空間的kgdb除錯。通常在核心中死掉的話,可以根據宕機位址再加反彙編,或者是addr2line找到宕機的函式或者是那一行,但是對於動態插入的模組卻不行。這是因為,核心在編譯的時候就把位址鏈結好了,執行的時候**段的位址空間在鏈結的時候就決定了。但是,對於模組來說的話,在insmod的時候,核心是動態的分配一段記憶體,在這段記憶體中完成模組和核心的鏈結,並決定該模組執行時的模組**段、資料段,等等。而且模組檔案本質就是乙個目標檔案,當然他比普通的目標檔案還含有更多一些幫助模組裝載的東西。這樣,我們如果在執行的時候宕機在模組中的話,即使核心最後列印出了宕機位址以及堆疊,我們也沒有辦法將這些位址與**對應。當然,如果該模組是帶-g編譯的話,運氣好的話,核心會列印出函式名字的堆疊。現在,我討論的時候如果只有位址,該如何和模組**對應。

首先,我們用objdum -d test.ko > test.asm的話。可以將模組檔案反彙編。但是因為模組是目標檔案,所以會看到,text段的位址是從0開始的。而該模組在核心在執行的時候,該模組的**段顯然不是在0位址。另外,該**段中你會看到函式間呼叫,以及函式內部跳轉都是用的b開頭的分支指令(僅限於mips和arm的體系結構的討論),分支指令跳轉是以pc為基準值前後跳轉的。除非,跳轉符號不屬於這個模組,則需要32位的跳轉。實際上,模組鏈結到核心的時候,模組的**段是作為乙個整體鏈結到核心,所以我們只需要知道模組鏈結到的基位址,再用宕機的位址減去這個基位址這就得到了,該位址在模組中**段的偏移,再通過剛才的反彙編檔案就找到了是死在那個函式中。而要得到各個模組的鏈結位址就很簡單了,直接cat /proc/modules就得到了。需要注意的是用__init修飾了的模組初始化函式,是放在單獨的段的,通常叫.init.text 。該段會在模組初始化完成後記憶體就釋放掉了。

說了這麼多,其實就一句話,通過cat /proc/modules獲得模組核心鏈結基位址,用宕機位址減去鏈結基位址得到模組內偏移,再反彙編,找該偏移對應的函式就找到了宕機函式。呵呵,這對於拷機宕機這種問題還是非常有幫助的。這篇文章很多涉及到編譯鏈結原理,以及elf檔案格式的細節,就不累述了,否則可能要整成一本書了。

crash除錯核心模組

wifi 模組出現panic時,怎麼根據fulldump去分析wifi問題,以及怎麼除錯wlan的ko檔案?這裡介紹linux下的crash工具來分析fulldump,當然也可以用trace32,gdb等其他工具.1.安裝crash工具 編譯和安裝 make target arm64 make in...

用gdb除錯核心模組

請讀者試用 本人開發搜尋頁面 速谷歌 本文也即 linux device drivers ldd3的第四章debuging techniques的讀書筆記之六,但我們不限於此內容。這章看得比較慢,最近比較懶,而陷入了文件工作中,我決定這章節不會有之七,在之六打住。在使用者程式中,有很多編譯工具同提供...

核心模組的除錯方法

核心可載入模組的除錯具有其特殊性。由於核心模組中各段的位址是在模組載入進核心的時候才最終確定的,所以 develop 機的gdb 無法得到各種符號位址資訊。所以,使用 kgdb 除錯模組所需要解決的乙個問題是,需要通過某種方法獲得可載入模組的最終載入位址資訊,並把這些資訊加入到 gdb環境中。i 在...