1 內(nèi)核調(diào)試以及工具總結(jié)
內(nèi)核總是那么捉摸不透, 內(nèi)核也會(huì)犯錯(cuò), 但是調(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)核中有三個(gè)常用的偽文件系統(tǒng): procfs, debugfs和sysfs.
它們都用于Linux內(nèi)核和用戶空間的數(shù)據(jù)交換, 但是適用的場(chǎng)景有所差異:
procfs
歷史最早, 最初就是用來跟內(nèi)核交互的唯一方式, 用來獲取處理器、內(nèi)存、設(shè)備驅(qū)動(dòng)、進(jìn)程等各種信息.sysfs
跟kobject
框架緊密聯(lián)系, 而kobject
是為設(shè)備驅(qū)動(dòng)模型而存在的, 所以sysfs
是為設(shè)備驅(qū)動(dòng)服務(wù)的.debugfs
從名字來看就是為debug
而生, 所以更加靈活.relayfs
是一個(gè)快速的轉(zhuǎn)發(fā)(relay)
數(shù)據(jù)的文件系統(tǒng), 它以其功能而得名. 它為那些需要從內(nèi)核空間轉(zhuǎn)發(fā)大量數(shù)據(jù)到用戶空間的工具和應(yīng)用提供了快速有效的轉(zhuǎn)發(fā)機(jī)制.
相關(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 用法簡(jiǎn)介: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ù)是只讀的. 實(shí)際上, 很多應(yīng)用嚴(yán)重地依賴于procfs, 因此它幾乎是必不可少的組件. 前面部分的幾個(gè)例子實(shí)際上已經(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ū)動(dòng)可以直接編譯到內(nèi)核, 也可以編譯成模塊, 編譯到內(nèi)核, 使用前一節(jié)介紹的方法通過內(nèi)核啟動(dòng)參數(shù)來向它們傳遞參數(shù), 如果編譯成模塊, 則可以通過命令行在插入模塊時(shí)傳遞參數(shù), 或者在運(yùn)行時(shí), 通過 sysfs
來設(shè)置或讀取模塊數(shù)據(jù).
Sysfs
是一個(gè)基于內(nèi)存的文件系統(tǒng), 實(shí)際上它基于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)核的各個(gè)子系統(tǒng)使用它. 用戶要想使用 sysfs
讀取和設(shè)置內(nèi)核參數(shù), 僅需裝載 sysfs
就可以通過文件操作應(yīng)用來讀取和設(shè)置內(nèi)核通過 sysfs
開放給用戶的各個(gè)參數(shù):
mkdir -p /sysfs
mount -t sysfs sysfs /sysfs
注意, 不要把 sysfs
和 sysctl
混淆, sysctl
是內(nèi)核的一些控制參數(shù), 其目的是方便用戶對(duì)內(nèi)核的行為進(jìn)行控制, 而 sysfs
僅僅是把內(nèi)核的 kobject
對(duì)象的層次關(guān)系與屬性開放給用戶查看, 因此 sysfs
的絕大部分是只讀的, 模塊作為一個(gè) kobject
也被出口到 sysfs
, 模塊參數(shù)則是作為模塊屬性出口的, 內(nèi)核實(shí)現(xiàn)者為模塊的使用提供了更靈活的方式, 允許用戶設(shè)置模塊參數(shù)在 sysfs
的可見性并允許用戶在編寫模塊時(shí)設(shè)置這些參數(shù)在 sysfs
下的訪問權(quán)限, 然后用戶就可以通過 sysfs
來查看和設(shè)置模塊參數(shù), 從而使得用戶能在模塊運(yùn)行時(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
語(yǔ)句, 另外如果開發(fā)者希望用戶空間應(yīng)用能夠改變內(nèi)核行為時(shí), printk
就無法實(shí)現(xiàn).
因此, 需要一種新的機(jī)制, 那只有在需要的時(shí)候使用, 它在需要時(shí)通過在一個(gè)虛擬文件系統(tǒng)中創(chuàng)建一個(gè)或多個(gè)文件來向用戶空間應(yīng)用提供調(diào)試信息.
有幾種方式可以實(shí)現(xiàn)上述要求:
- 使用
procfs
, 在/proc
創(chuàng)建文件輸出調(diào)試信息, 但是procfs
對(duì)于大于一個(gè)內(nèi)存頁(yè)(對(duì)于x86
是4K
)的輸出比較麻煩, 而且速度慢, 有時(shí)回出現(xiàn)一些意想不到的問題. - 使用
sysfs
(2.6
內(nèi)核引入的新的虛擬文件系統(tǒng)), 在很多情況下, 調(diào)試信息可以存放在那里, 但是sysfs主要用于系統(tǒng)管理,它希望每一個(gè)文件對(duì)應(yīng)內(nèi)核的一個(gè)變量,如果使用它輸出復(fù)雜的數(shù)據(jù)結(jié)構(gòu)或調(diào)試信息是非常困難的. - 使用
libfs
創(chuàng)建一個(gè)新的文件系統(tǒng), 該方法極其靈活, 開發(fā)者可以為新文件系統(tǒng)設(shè)置一些規(guī)則, 使用libfs
使得創(chuàng)建新文件系統(tǒng)更加簡(jiǎn)單, 但是仍然超出了一個(gè)開發(fā)者的想象.
為了使得開發(fā)者更加容易使用這樣的機(jī)制, Greg Kroah-Hartman
開發(fā)了 debugfs
(在 2.6.11
中第一次引入), 它是一個(gè)虛擬文件系統(tǒng), 專門用于輸出調(diào)試信息, 該文件系統(tǒng)非常小, 很容易使用, 可以在配置內(nèi)核時(shí)選擇是否構(gòu)件到內(nèi)核中, 在不選擇它的情況下, 使用它提供的API的內(nèi)核部分不需要做任何改動(dòng).
相關(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ū)動(dòng)調(diào)試的Debugfs的使用簡(jiǎn)介: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 用法簡(jiǎn)介: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 運(yùn)用debugfs調(diào)試方法:http://www.xuebuyuan.com/1023006.html
2.4 relayfs文件系統(tǒng)
relayfs
是一個(gè)快速的轉(zhuǎn)發(fā)(relay
)數(shù)據(jù)的文件系統(tǒng), 它以其功能而得名. 它為那些需要從內(nèi)核空間轉(zhuǎn)發(fā)大量數(shù)據(jù)到用戶空間的工具和應(yīng)用提供了快速有效的轉(zhuǎn)發(fā)機(jī)制.
Channel
是 relayfs
文件系統(tǒng)定義的一個(gè)主要概念, 每一個(gè) channel
由一組內(nèi)核緩存組成, 每一個(gè) CPU
有一個(gè)對(duì)應(yīng)于該 channel
的內(nèi)核緩存, 每一個(gè)內(nèi)核緩存用一個(gè)在 relayfs
文件系統(tǒng)中的文件文件表示, 內(nèi)核使用 relayfs
提供的寫函數(shù)把需要轉(zhuǎn)發(fā)給用戶空間的數(shù)據(jù)快速地寫入當(dāng)前 CPU
上的 channel
內(nèi)核緩存, 用戶空間應(yīng)用通過標(biāo)準(zhǔn)的文件 I/
O函數(shù)在對(duì)應(yīng)的 channel
文件中可以快速地取得這些被轉(zhuǎn)發(fā)出的數(shù)據(jù) mmap
來. 寫入到 channel
中的數(shù)據(jù)的格式完全取決于內(nèi)核中創(chuàng)建channel
的模塊或子系統(tǒng).
relayfs
的用戶空間API
:
relayfs
實(shí)現(xiàn)了四個(gè)標(biāo)準(zhǔn)的文件 I/O
函數(shù), open、mmap、poll和close
注意 : 用戶態(tài)應(yīng)用在使用上述 API 時(shí)必須保證已經(jīng)掛載了 relayfs 文件系統(tǒng), 但內(nèi)核在創(chuàng)建和使用 channel時(shí)不需要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
有一個(gè)缺陷, 如果輸出內(nèi)容大于1個(gè)內(nèi)存頁(yè), 需要多次讀,因此處理起來很難, 另外, 如果輸出太大, 速度比較慢, 有時(shí)會(huì)出現(xiàn)一些意想不到的情況, Alexander Viro
實(shí)現(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機(jī)制:http://blog.csdn.net/a8039974/article/details/24052619
3 printk
在內(nèi)核調(diào)試技術(shù)之中, 最簡(jiǎn)單的就是 printk
的使用了, 它的用法和C語(yǔ)言應(yīng)用程序中的 printf
使用類似, 在應(yīng)用程序中依靠的是 stdio.h
中的庫(kù), 而在 linux
內(nèi)核中沒有這個(gè)庫(kù), 所以在 linux
內(nèi)核中,實(shí)現(xiàn)了自己的一套庫(kù)函數(shù), printk
就是標(biāo)準(zhǔn)的輸出函數(shù)
相關(guān)資料鏈接:
linux內(nèi)核調(diào)試技術(shù)之printk:http://www.cnblogs.com/veryStrong/p/6218383.html
調(diào)整內(nèi)核printk的打印級(jí)別:http://blog.csdn.net/tonywgx/article/details/17504001
linux設(shè)備驅(qū)動(dòng)學(xué)習(xí)筆記–內(nèi)核調(diào)試方法之printk:http://blog.csdn.net/itsenlin/article/details/43205983
4 ftrace && trace-cmd
4.1 trace && ftrace
Linux
當(dāng)前版本中, 功能最強(qiáng)大的調(diào)試、跟蹤手段. 其最基本的功能是提供了動(dòng)態(tài)和靜態(tài)探測(cè)點(diǎn), 用于探測(cè)內(nèi)核中指定位置上的相關(guān)信息.
靜態(tài)探測(cè)點(diǎn), 是在內(nèi)核代碼中調(diào)用 ftrace
提供的相應(yīng)接口實(shí)現(xiàn), 稱之為靜態(tài)是因?yàn)? 是在內(nèi)核代碼中寫死的, 靜態(tài)編譯到內(nèi)核代碼中的, 在內(nèi)核編譯后, 就不能再動(dòng)態(tài)修改. 在開啟 ftrace
相關(guān)的內(nèi)核配置選項(xiàng)后, 內(nèi)核中已經(jīng)在一些關(guān)鍵的地方設(shè)置了靜態(tài)探測(cè)點(diǎn), 需要使用時(shí), 即可查看到相應(yīng)的信息.
動(dòng)態(tài)探測(cè)點(diǎn), 基本原理為 : 利用 mcount
機(jī)制, 在內(nèi)核編譯時(shí), 在每個(gè)函數(shù)入口保留數(shù)個(gè)字節(jié), 然后在使用 ftrace
時(shí), 將保留的字節(jié)替換為需要的指令, 比如跳轉(zhuǎn)到需要的執(zhí)行探測(cè)操作的代碼。
ftrace
的作用是幫助開發(fā)人員了解 Linux
內(nèi)核的運(yùn)行時(shí)行為, 以便進(jìn)行故障調(diào)試或性能分析.
最早 ftrace
是一個(gè) function tracer
, 僅能夠記錄內(nèi)核的函數(shù)調(diào)用流程. 如今 ftrace
已經(jīng)成為一個(gè)
framework
, 采用 plugin
的方式支持開發(fā)人員添加更多種類的 trace
功能.
Ftrace
由 RedHat
的 Steve Rostedt
負(fù)責(zé)維護(hù). 到 2.6.30
為止, 已經(jīng)支持的 tracer
包括 :
這里還沒有列出所有的 tracer
, ftrace
是目前非常活躍的開發(fā)領(lǐng)域, 新的 tracer
將不斷被加入內(nèi)核。
相關(guān)資料鏈接:
ftrace和它的前端工具trace-cmd(深入了解Linux系統(tǒng)的利器):http://blog.yufeng.info/archives/1012
ftrace 簡(jiǎn)介: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
的前段工具, 用于分分析核性能.
他們相當(dāng)于是一個(gè) /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ì)就是對(duì)/sys/kernel/debug/tracing/events
下各個(gè)模塊進(jìn)行操作, 收集數(shù)據(jù)并解析
-
內(nèi)核
+關(guān)注
關(guān)注
3文章
1366瀏覽量
40236 -
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
6909瀏覽量
88850 -
Linux
+關(guān)注
關(guān)注
87文章
11232瀏覽量
208960 -
開發(fā)
+關(guān)注
關(guān)注
0文章
367瀏覽量
40811
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論