1 內(nèi)核調(diào)試以及工具總結(jié)
內(nèi)核總是那么捉摸不透, 內(nèi)核也會犯錯, 但是調(diào)試卻不能像用戶空間程序那樣, 為此內(nèi)核開發(fā)者為我們提供了一系列的工具和系統(tǒng)來支持內(nèi)核的調(diào)試.
內(nèi)核的調(diào)試, 其本質(zhì)是內(nèi)核空間與用戶空間的數(shù)據(jù)交換, 內(nèi)核開發(fā)者們提供了多樣的形式來完成這一功能.


2 用戶空間與內(nèi)核空間數(shù)據(jù)交換的文件系統(tǒng)
內(nèi)核中有三個常用的偽文件系統(tǒng): procfs, debugfs和sysfs.

它們都用于Linux內(nèi)核和用戶空間的數(shù)據(jù)交換, 但是適用的場景有所差異:
procfs歷史最早, 最初就是用來跟內(nèi)核交互的唯一方式, 用來獲取處理器、內(nèi)存、設(shè)備驅(qū)動、進程等各種信息.sysfs跟kobject框架緊密聯(lián)系, 而kobject是為設(shè)備驅(qū)動模型而存在的, 所以sysfs是為設(shè)備驅(qū)動服務(wù)的.debugfs從名字來看就是為debug而生, 所以更加靈活.relayfs是一個快速的轉(zhuǎn)發(fā)(relay)數(shù)據(jù)的文件系統(tǒng), 它以其功能而得名. 它為那些需要從內(nèi)核空間轉(zhuǎn)發(fā)大量數(shù)據(jù)到用戶空間的工具和應(yīng)用提供了快速有效的轉(zhuǎn)發(fā)機制.
相關(guān)資料鏈接:
在 Linux 下用戶空間與內(nèi)核空間數(shù)據(jù)交換的方式, 第 2 部分: procfs、seq_file、debugfs和relayfs:http://www.ibm.com/developerworks/cn/linux/l-kerns-usrs2/
Linux 文件系統(tǒng):procfs, sysfs, debugfs 用法簡介:http://www.tinylab.org/show-the-usage-of-procfs-sysfs-debugfs/
2.1 procfs文件系統(tǒng)
ProcFs介紹
procfs 是比較老的一種用戶態(tài)與內(nèi)核態(tài)的數(shù)據(jù)交換方式, 內(nèi)核的很多數(shù)據(jù)都是通過這種方式出口給用戶的, 內(nèi)核的很多參數(shù)也是通過這種方式來讓用戶方便設(shè)置的. 除了 sysctl 出口到 /proc 下的參數(shù), procfs 提供的大部分內(nèi)核參數(shù)是只讀的. 實際上, 很多應(yīng)用嚴重地依賴于procfs, 因此它幾乎是必不可少的組件. 前面部分的幾個例子實際上已經(jīng)使用它來出口內(nèi)核數(shù)據(jù), 但是并沒有講解如何使用, 本節(jié)將講解如何使用procfs.
-
參考資料:
用戶空間與內(nèi)核空間數(shù)據(jù)交換的方式(2)——procfs:http://www.cnblogs.com/hoys/archive/2011/04/10/2011141.html
2.2 sysfs文件系統(tǒng)
內(nèi)核子系統(tǒng)或設(shè)備驅(qū)動可以直接編譯到內(nèi)核, 也可以編譯成模塊, 編譯到內(nèi)核, 使用前一節(jié)介紹的方法通過內(nèi)核啟動參數(shù)來向它們傳遞參數(shù), 如果編譯成模塊, 則可以通過命令行在插入模塊時傳遞參數(shù), 或者在運行時, 通過 sysfs 來設(shè)置或讀取模塊數(shù)據(jù).
Sysfs 是一個基于內(nèi)存的文件系統(tǒng), 實際上它基于ramfs, sysfs 提供了一種把內(nèi)核數(shù)據(jù)結(jié)構(gòu), 它們的屬性以及屬性與數(shù)據(jù)結(jié)構(gòu)的聯(lián)系開放給用戶態(tài)的方式, 它與 kobject 子系統(tǒng)緊密地結(jié)合在一起, 因此內(nèi)核開發(fā)者不需要直接使用它, 而是內(nèi)核的各個子系統(tǒng)使用它. 用戶要想使用 sysfs 讀取和設(shè)置內(nèi)核參數(shù), 僅需裝載 sysfs 就可以通過文件操作應(yīng)用來讀取和設(shè)置內(nèi)核通過 sysfs 開放給用戶的各個參數(shù):
mkdir -p /sysfs
mount -t sysfs sysfs /sysfs
注意, 不要把 sysfs 和 sysctl 混淆, sysctl 是內(nèi)核的一些控制參數(shù), 其目的是方便用戶對內(nèi)核的行為進行控制, 而 sysfs 僅僅是把內(nèi)核的 kobject 對象的層次關(guān)系與屬性開放給用戶查看, 因此 sysfs的絕大部分是只讀的, 模塊作為一個 kobject 也被出口到 sysfs, 模塊參數(shù)則是作為模塊屬性出口的, 內(nèi)核實現(xiàn)者為模塊的使用提供了更靈活的方式, 允許用戶設(shè)置模塊參數(shù)在 sysfs 的可見性并允許用戶在編寫模塊時設(shè)置這些參數(shù)在 sysfs 下的訪問權(quán)限, 然后用戶就可以通過 sysfs 來查看和設(shè)置模塊參數(shù), 從而使得用戶能在模塊運行時控制模塊行為.
相關(guān)資料鏈接:
用戶空間與內(nèi)核空間數(shù)據(jù)交換的方式(6)——模塊參數(shù)與sysfs:http://www.cnblogs.com/hoys/archive/2011/04/10/2011470.html
2.3 debugfs文件系統(tǒng)
內(nèi)核開發(fā)者經(jīng)常需要向用戶空間應(yīng)用輸出一些調(diào)試信息, 在穩(wěn)定的系統(tǒng)中可能根本不需要這些調(diào)試信息, 但是在開發(fā)過程中, 為了搞清楚內(nèi)核的行為, 調(diào)試信息非常必要, printk可能是用的最多的, 但它并不是最好的, 調(diào)試信息只是在開發(fā)中用于調(diào)試, 而 printk 將一直輸出, 因此開發(fā)完畢后需要清除不必要的 printk 語句, 另外如果開發(fā)者希望用戶空間應(yīng)用能夠改變內(nèi)核行為時, printk 就無法實現(xiàn).
因此, 需要一種新的機制, 那只有在需要的時候使用, 它在需要時通過在一個虛擬文件系統(tǒng)中創(chuàng)建一個或多個文件來向用戶空間應(yīng)用提供調(diào)試信息.
有幾種方式可以實現(xiàn)上述要求:
- 使用
procfs, 在/proc創(chuàng)建文件輸出調(diào)試信息, 但是procfs對于大于一個內(nèi)存頁(對于x86是4K)的輸出比較麻煩, 而且速度慢, 有時回出現(xiàn)一些意想不到的問題. - 使用
sysfs(2.6內(nèi)核引入的新的虛擬文件系統(tǒng)), 在很多情況下, 調(diào)試信息可以存放在那里, 但是sysfs主要用于系統(tǒng)管理,它希望每一個文件對應(yīng)內(nèi)核的一個變量,如果使用它輸出復(fù)雜的數(shù)據(jù)結(jié)構(gòu)或調(diào)試信息是非常困難的. - 使用
libfs創(chuàng)建一個新的文件系統(tǒng), 該方法極其靈活, 開發(fā)者可以為新文件系統(tǒng)設(shè)置一些規(guī)則, 使用libfs使得創(chuàng)建新文件系統(tǒng)更加簡單, 但是仍然超出了一個開發(fā)者的想象.
為了使得開發(fā)者更加容易使用這樣的機制, Greg Kroah-Hartman 開發(fā)了 debugfs(在 2.6.11 中第一次引入), 它是一個虛擬文件系統(tǒng), 專門用于輸出調(diào)試信息, 該文件系統(tǒng)非常小, 很容易使用, 可以在配置內(nèi)核時選擇是否構(gòu)件到內(nèi)核中, 在不選擇它的情況下, 使用它提供的API的內(nèi)核部分不需要做任何改動.
相關(guān)資料鏈接:
用戶空間與內(nèi)核空間數(shù)據(jù)交換的方式(1)——debugfs:http://www.cnblogs.com/hoys/archive/2011/04/10/2011124.html
Linux內(nèi)核里的DebugFS:http://www.cnblogs.com/wwang/archive/2011/01/17/1937609.html
Linux驅(qū)動調(diào)試的Debugfs的使用簡介:http://soft.chinabyte.com/os/110/12377610.shtml
Linux Debugfs文件系統(tǒng)介紹及使用:http://blog.sina.com.cn/s/blog_40d2f1c80100p7u2.html
Linux內(nèi)核里的DebugFS:http://www.cnblogs.com/wwang/archive/2011/01/17/1937609.html
Debugging the Linux Kernel with debugfs:http://opensourceforu.com/2010/10/debugging-linux-kernel-with-debugfs/
debugfs-seq_file:http://lxr.free-electrons.com/source/drivers/base/power/wakeup.c
Linux Debugfs文件系統(tǒng)介紹及使用:http://blog.sina.com.cn/s/blog_40d2f1c80100p7u2.html
Linux 文件系統(tǒng):procfs, sysfs, debugfs 用法簡介:http://www.tinylab.org/show-the-usage-of-procfs-sysfs-debugfs/
用戶空間與內(nèi)核空間數(shù)據(jù)交換的方式(1)——debugfs:http://www.cnblogs.com/hoys/archive/2011/04/10/2011124.html
Linux 運用debugfs調(diào)試方法:http://www.xuebuyuan.com/1023006.html
2.4 relayfs文件系統(tǒng)
relayfs 是一個快速的轉(zhuǎn)發(fā)(relay)數(shù)據(jù)的文件系統(tǒng), 它以其功能而得名. 它為那些需要從內(nèi)核空間轉(zhuǎn)發(fā)大量數(shù)據(jù)到用戶空間的工具和應(yīng)用提供了快速有效的轉(zhuǎn)發(fā)機制.
Channel 是 relayfs 文件系統(tǒng)定義的一個主要概念, 每一個 channel 由一組內(nèi)核緩存組成, 每一個 CPU 有一個對應(yīng)于該 channel 的內(nèi)核緩存, 每一個內(nèi)核緩存用一個在 relayfs 文件系統(tǒng)中的文件文件表示, 內(nèi)核使用 relayfs 提供的寫函數(shù)把需要轉(zhuǎn)發(fā)給用戶空間的數(shù)據(jù)快速地寫入當前 CPU 上的 channel 內(nèi)核緩存, 用戶空間應(yīng)用通過標準的文件 I/ O函數(shù)在對應(yīng)的 channel 文件中可以快速地取得這些被轉(zhuǎn)發(fā)出的數(shù)據(jù) mmap 來. 寫入到 channel 中的數(shù)據(jù)的格式完全取決于內(nèi)核中創(chuàng)建channel 的模塊或子系統(tǒng).
relayfs 的用戶空間API :
relayfs 實現(xiàn)了四個標準的文件 I/O 函數(shù), open、mmap、poll和close

注意 : 用戶態(tài)應(yīng)用在使用上述 API 時必須保證已經(jīng)掛載了 relayfs 文件系統(tǒng), 但內(nèi)核在創(chuàng)建和使用 channel時不需要relayfs 已經(jīng)掛載. 下面命令將把 relayfs 文件系統(tǒng)掛載到 /mnt/relay.
相關(guān)資料鏈接:
用戶空間與內(nèi)核空間數(shù)據(jù)交換的方式(4)——relayfs:http://www.cnblogs.com/hoys/archive/2011/04/10/2011270.html
Relay:一種內(nèi)核到用戶空間的高效數(shù)據(jù)傳輸技術(shù):https://www.ibm.com/developerworks/cn/linux/l-cn-relay/
2.5 seq_file
一般地, 內(nèi)核通過在 procfs 文件系統(tǒng)下建立文件來向用戶空間提供輸出信息, 用戶空間可以通過任何文本閱讀應(yīng)用查看該文件信息, 但是 procfs 有一個缺陷, 如果輸出內(nèi)容大于1個內(nèi)存頁, 需要多次讀,因此處理起來很難, 另外, 如果輸出太大, 速度比較慢, 有時會出現(xiàn)一些意想不到的情況, Alexander Viro 實現(xiàn)了一套新的功能, 使得內(nèi)核輸出大文件信息更容易, 該功能出現(xiàn)在 2.4.15(包括 2.4.15)以后的所有 2.4 內(nèi)核以及 2.6 內(nèi)核中, 尤其是在 2.6 內(nèi)核中,已經(jīng)大量地使用了該功能
相關(guān)資料鏈接:
用戶空間與內(nèi)核空間數(shù)據(jù)交換的方式(3)——seq_file:http://www.cnblogs.com/hoys/archive/2011/04/10/2011261.html
內(nèi)核proc文件系統(tǒng)與seq接口(4)—seq_file接口編程淺析:http://blog.chinaunix.net/uid-20543672-id-3235254.html
Linux內(nèi)核中的seq操作:http://www.cnblogs.com/qq78292959/archive/2012/06/13/2547335.html
seq_file源碼分析:http://www.cppblog.com/csjiaxin/articles/136681.html
用序列文件(seq_file)接口導(dǎo)出常用數(shù)據(jù)結(jié)構(gòu):http://blog.chinaunix.net/uid-317451-id-92670.html
seq_file機制:http://blog.csdn.net/a8039974/article/details/24052619
3 printk
在內(nèi)核調(diào)試技術(shù)之中, 最簡單的就是 printk 的使用了, 它的用法和C語言應(yīng)用程序中的 printf 使用類似, 在應(yīng)用程序中依靠的是 stdio.h 中的庫, 而在 linux 內(nèi)核中沒有這個庫, 所以在 linux 內(nèi)核中,實現(xiàn)了自己的一套庫函數(shù), printk 就是標準的輸出函數(shù)
相關(guān)資料鏈接:
linux內(nèi)核調(diào)試技術(shù)之printk:http://www.cnblogs.com/veryStrong/p/6218383.html
調(diào)整內(nèi)核printk的打印級別:http://blog.csdn.net/tonywgx/article/details/17504001
linux設(shè)備驅(qū)動學習筆記–內(nèi)核調(diào)試方法之printk:http://blog.csdn.net/itsenlin/article/details/43205983
4 ftrace && trace-cmd
4.1 trace && ftrace
Linux當前版本中, 功能最強大的調(diào)試、跟蹤手段. 其最基本的功能是提供了動態(tài)和靜態(tài)探測點, 用于探測內(nèi)核中指定位置上的相關(guān)信息.
靜態(tài)探測點, 是在內(nèi)核代碼中調(diào)用 ftrace 提供的相應(yīng)接口實現(xiàn), 稱之為靜態(tài)是因為, 是在內(nèi)核代碼中寫死的, 靜態(tài)編譯到內(nèi)核代碼中的, 在內(nèi)核編譯后, 就不能再動態(tài)修改. 在開啟 ftrace 相關(guān)的內(nèi)核配置選項后, 內(nèi)核中已經(jīng)在一些關(guān)鍵的地方設(shè)置了靜態(tài)探測點, 需要使用時, 即可查看到相應(yīng)的信息.
動態(tài)探測點, 基本原理為 : 利用 mcount 機制, 在內(nèi)核編譯時, 在每個函數(shù)入口保留數(shù)個字節(jié), 然后在使用 ftrace時, 將保留的字節(jié)替換為需要的指令, 比如跳轉(zhuǎn)到需要的執(zhí)行探測操作的代碼。
ftrace 的作用是幫助開發(fā)人員了解 Linux 內(nèi)核的運行時行為, 以便進行故障調(diào)試或性能分析.
最早 ftrace 是一個 function tracer, 僅能夠記錄內(nèi)核的函數(shù)調(diào)用流程. 如今 ftrace 已經(jīng)成為一個
framework, 采用 plugin 的方式支持開發(fā)人員添加更多種類的 trace 功能.
Ftrace 由 RedHat 的 Steve Rostedt 負責維護. 到 2.6.30 為止, 已經(jīng)支持的 tracer 包括 :

這里還沒有列出所有的 tracer, ftrace 是目前非?;钴S的開發(fā)領(lǐng)域, 新的 tracer 將不斷被加入內(nèi)核。
相關(guān)資料鏈接:
ftrace和它的前端工具trace-cmd(深入了解Linux系統(tǒng)的利器):http://blog.yufeng.info/archives/1012
ftrace 簡介:https://www.ibm.com/developerworks/cn/linux/l-cn-ftrace/
內(nèi)核性能調(diào)試–ftrace:http://blog.chinaunix.net/uid-20589411-id-3501525.html
使用 ftrace 調(diào)試 Linux 內(nèi)核,第 1 部分:https://www.ibm.com/developerworks/cn/linux/l-cn-ftrace1
ftrace的使用:http://blog.csdn.net/cybertan/article/details/8258394
[轉(zhuǎn)]Linux內(nèi)核跟蹤之trace框架分析:http://blog.chinaunix.net/uid-24063584-id-2642103.html
Linux trace使用入門:http://blog.csdn.net/jscese/article/details/46415531
4.2 ftrace前端工具trace-cmd
- trace-cmd 介紹
trace-cmd 和 開源的 kernelshark 均是內(nèi)核Ftrace 的前段工具, 用于分分析核性能.
他們相當于是一個 /sys/kernel/debug/tracing 中文件系統(tǒng)接口的封裝, 為用戶提供了更加直接和方便的操作.
- 使用
# 收集信息
sudo trace-cmd reord subsystem:tracing
# 解析結(jié)果
#sudo trace-cmd report
trace-cmd: A front-end for Ftrace:https://lwn.net/Articles/410200/
其本質(zhì)就是對/sys/kernel/debug/tracing/events 下各個模塊進行操作, 收集數(shù)據(jù)并解析
-
內(nèi)核
+關(guān)注
關(guān)注
4文章
1476瀏覽量
43098 -
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7349瀏覽量
95054 -
Linux
+關(guān)注
關(guān)注
88文章
11822瀏覽量
219600 -
開發(fā)
+關(guān)注
關(guān)注
0文章
380瀏覽量
42244
發(fā)布評論請先 登錄
Linux內(nèi)核開發(fā)工具介紹
Linux內(nèi)核鏡像bzImage和rootfs的制作、安裝及調(diào)試過程
Linux內(nèi)核學習筆記:printk調(diào)試
學會Linux內(nèi)核調(diào)試方法!
快速理解什么是Linux內(nèi)核以及Linux內(nèi)核的內(nèi)容
嵌入式LINUX系統(tǒng)內(nèi)核和內(nèi)核模塊調(diào)試教程
嵌入式LINUX系統(tǒng)內(nèi)核和內(nèi)核模塊調(diào)試
Linux內(nèi)核調(diào)試的方式以及工具集錦
Linux內(nèi)核調(diào)試的方式以及工具匯總(下)
Linux內(nèi)核調(diào)試方式以及工具總結(jié)
Linux內(nèi)核調(diào)試的方式以及工具匯總(上)
評論