Linux跟蹤工具:虛幻的肥皂鬧劇
Linux跟蹤工具在內(nèi)核的發(fā)展就像是肥皂劇一樣,劇情婉轉(zhuǎn),主題反復(fù)并且相互競(jìng)爭(zhēng)。本文試圖總結(jié)當(dāng)前Linux中眾多跟蹤工具現(xiàn)狀和歷史原因。
Attention: 編者對(duì)于以下內(nèi)容并非親歷者(主要來自LWN和maillist),如有歪曲請(qǐng)拍磚。以下部分雖屬八卦,但是,學(xué)習(xí)一些模塊的設(shè)計(jì)方案和歷史進(jìn)程是我學(xué)習(xí)方法論的一部分,從這些糾結(jié)的方案和博弈中可以看到很多權(quán)衡和利弊幫助更好的獲得其中的思想,以下文字是連帶產(chǎn)物。學(xué)習(xí)使用這些性能工具推薦以下資源。
- SystemTap
- LTTng
- latencytop深度了解你的Linux系統(tǒng)的延遲
- 通過blktrace, debugfs分析磁盤IO
- SystemTap–Linux下的萬能觀測(cè)工具
Why Trace the kernel?
很多人在接觸這類工具時(shí)可能會(huì)感到困惑,內(nèi)核代碼早就已經(jīng)優(yōu)化的非常好了并且基本不會(huì)有什么Bug,那么為什么還需要插入這么多探針去查看內(nèi)核的狀態(tài)? 其實(shí)這種工具在生產(chǎn)環(huán)境中被很多人使用去跟蹤問題,比如系統(tǒng)此時(shí)無法理解的行為(CPU居高,IO忙),這時(shí)候系統(tǒng)管理員需要利用這種工具在不干擾正常系統(tǒng)運(yùn)作的情況下去Linux這個(gè)龐大的內(nèi)核中查找原因。
Dtrace Envy和SystemTap
首先,我們先來介紹Dtrace Envy。Linux社區(qū)中過去有一個(gè)名詞叫Dtrace Envy,從字母上可以發(fā)現(xiàn)Linux社區(qū)對(duì)Dtrace的深惡痛絕,不僅是Dtrace在以前的Linux沒有相應(yīng)如此強(qiáng)大的實(shí)現(xiàn),而且Dtrace經(jīng)常被Sun公司用來作營(yíng)銷手段的噱頭(同樣的還有ZFS)與Linux進(jìn)行對(duì)比。
那時(shí)還是07年,大家在提到Solaris系統(tǒng)時(shí),Dtrace總是在人們關(guān)注的前幾個(gè)特征。而SystemTap當(dāng)時(shí)還在幾個(gè)大公司Red Hat、Intel、IBM和日立內(nèi)部使用,Dtrace的擁護(hù)者會(huì)嘲諷SystemTap只是個(gè)山寨貨,而SystemTap的粉絲認(rèn)為SystemTap是個(gè)獨(dú)立發(fā)展的項(xiàng)目,并且以超越Dtrace為目標(biāo)。
這兩個(gè)工具都是在內(nèi)核中插入探針,當(dāng)一個(gè)線程執(zhí)行碰到探針時(shí),預(yù)先定義的腳本(D語言腳本或者SystemTap腳本)就會(huì)運(yùn)行。
Dtrace使用了大量的預(yù)先定義的探針插入到Solaris內(nèi)核中,這種方式稱為靜態(tài)探針,這些探針都在Dtrace的文檔中做了詳述。并且一些簡(jiǎn)單的通配符(*)可以用來實(shí)現(xiàn)多個(gè)探針的選擇。Sun宣稱無用的探針并不會(huì)增加太多的負(fù)載。
SystemTap沒有采用Dtrace的方式,估計(jì)是SystemTap沒有人有這么大精力去實(shí)現(xiàn)大量的靜態(tài)探針放到內(nèi)核中(Linus會(huì)發(fā)飆的)。SystemTap采用的動(dòng)態(tài)探針(kprobes實(shí)現(xiàn)),它是在內(nèi)核運(yùn)行時(shí)被動(dòng)態(tài)插入。SystemTap采用腳本語言來定義一些動(dòng)作并且打開一些啟用的探針來(SystemTap的探針庫)插入到內(nèi)核中,沒有用到的探針不會(huì)插入。
從上述的差異可以看到Dtrace的靜態(tài)探針是有優(yōu)勢(shì)的,首先Dtrace大量的探針是被預(yù)定義并且可以被很好的文檔化(這對(duì)于系統(tǒng)管理員是非常好的,它們通常不熟悉內(nèi)核源碼),而SystemTap是可以在內(nèi)核的任意位置,這就需要開發(fā)者需要熟悉內(nèi)核的源碼并且把探針放到合適的位置。這就可能帶來安全性的問題,一些不恰當(dāng)?shù)奶结樂胖檬菚?huì)帶來系統(tǒng)崩潰的(這種情況非常少),即使非常少的位置是敏感的,但也足以使使用者感到不便,需要時(shí)時(shí)擔(dān)心可能的不恰當(dāng)觸發(fā)。當(dāng)然,SystemTap也有少量的預(yù)定義探針。
接著我們比較兩者的語言,Dtrace采用的D語言同樣繼承了安全的原則,它運(yùn)行在虛擬機(jī)中并且?guī)в邪踩珯z測(cè),并且拒絕控制語句(只有三元操作符),但在探針上可以附著表達(dá)式(相對(duì)于一個(gè)”if”)。而SystemTap同樣采取了大刀闊斧的姿態(tài),不僅有完備的控制語句,SystemTap腳本(STP)直接翻譯成C,并且在SystemTap腳本中可以嵌入C。可以想象,在這里面如果出現(xiàn)了死循環(huán)就基本意味著crash了。
Kernel summit 2008的故事
08年,雖然SystemTap有了長(zhǎng)足的發(fā)展,但是內(nèi)核社區(qū)和SystemTap項(xiàng)目團(tuán)隊(duì)仍然沒有一個(gè)很好的溝通和協(xié)商。SystemTap仍然沒有進(jìn)入普通用戶的工具范疇,在kernel summit中,Matthew Wilcox表示Dtrace已經(jīng)對(duì)Linux造成了足夠的威脅Ksummit-2008-discuss DTrace,Linux通常被認(rèn)為是新技術(shù)的前沿,但是當(dāng)Sun把Solaris開放后,一系列的新特征已經(jīng)領(lǐng)先Linux,比如ZFS和Dtrace。
即使當(dāng)時(shí)SystemTap和Btrfs被認(rèn)為是Linux對(duì)抗的利器,但是,在社區(qū)還是有人對(duì)SystemTap表示失望,James Bottomley(iSCSI貢獻(xiàn)者)在郵件中提到Ksummit-2008-discuss DTrace,就好像在Winodws用戶期望在Linux有Outlook一樣,SystemTap只不過是Solaris用戶到Linux期望有一個(gè)一樣的工具,同時(shí),James Bottomley表示SystemTap非常難用并且造成系統(tǒng)的崩潰。另一個(gè)Ted Ts’o同樣贊成SystemTap非常難以使用,但是他期望在SystemTap增加更多的”tapsets”來幫助對(duì)內(nèi)核不熟悉的人更好的使用SystemTap。
SystemTap的開發(fā)者Frank Ch. Eigler表示SystemTap早已考慮性能、難以使用的問題并且正在解決中,他認(rèn)為內(nèi)核社區(qū)缺少與SystemTap團(tuán)隊(duì)的溝通,并且提出了一系列的建議希望內(nèi)核團(tuán)隊(duì)參與到SystemTap與kernel的整合中來Frank Ch. Eigler fche at redhat.com。
但是,Ted Ts’o同樣回應(yīng)稱SystemTap只會(huì)將”tapsets”的開發(fā)任務(wù)交給內(nèi)核,而不去思考如何讓SystemTap變得易用并且更容易與內(nèi)核整合,他同時(shí)指責(zé)SystemTap光想著讓企業(yè)發(fā)行版使用,而不去努力改善與內(nèi)核的問題Theodore Tso tytso at mit.edu。
Frank Ch. Eigler表示大部分系統(tǒng)管理員是不會(huì)去使用SystemTap去思考內(nèi)核的性能追蹤,SystemTap通常是被整合到PostgreSQL這種基礎(chǔ)軟件中來使用,因此,SystemTap更加注重對(duì)此類問題的解決。
同時(shí),社區(qū)中有人期望把Dtrace移植到Linux中,但是這也困難重重,先不說Dtrace移植到Linux主線的技術(shù)問題,光光是CDDL協(xié)議就是不容于Linux的。好吧,接下來就是各種水友開始討論CDDL與GPL的協(xié)議問題(一群程序員開始Google。。。)
最后還是Linus強(qiáng)調(diào)了最重要的一點(diǎn),這個(gè)同時(shí)也是針對(duì)utrace的:SystemTap的實(shí)現(xiàn)是不被內(nèi)核開發(fā)者喜歡的,因?yàn)樗鼊?chuàng)造、利用內(nèi)核模塊的實(shí)現(xiàn)是不同于內(nèi)核的,對(duì)于SystemTap的細(xì)節(jié)如鎖實(shí)現(xiàn)和使用等等都是off kernel的。它希望SystemTap在實(shí)現(xiàn)設(shè)計(jì)上能離內(nèi)核越來越近。
ptrace
在介紹utrace之前首先需要介紹ptrace。它是Linux內(nèi)核跟蹤工具的化石,過去(07年以前)很長(zhǎng)一段時(shí)間里,大部分人利用它來調(diào)試應(yīng)用或者內(nèi)核模塊,但是它的問題也很多,低效(需要內(nèi)核/用戶態(tài)切換)、實(shí)現(xiàn)難以維護(hù)(架構(gòu)設(shè)計(jì)混亂)、用戶難以使用(接口復(fù)雜)、一個(gè)進(jìn)程只能被一個(gè)進(jìn)程跟蹤(使用信號(hào)方法跟蹤進(jìn)程,信號(hào)使得目標(biāo)只能wait一個(gè)進(jìn)程)、會(huì)改變跟蹤進(jìn)程的狀態(tài)(進(jìn)程父子關(guān)系)、打斷系統(tǒng)調(diào)用并且一直有大量的安全問題存在。
ptrace的維護(hù)者在utrace出現(xiàn)之后就已經(jīng)在呼吁讓ptrace基于utrace實(shí)現(xiàn),因?yàn)閜trace代碼是混亂的,散亂在各個(gè)架構(gòu)中,維護(hù)者早已經(jīng)對(duì)橫跨多個(gè)架構(gòu)的代碼厭倦了。
我們需要注意到gdb和strace都是基于ptrace,這個(gè)原因也導(dǎo)致了ustrace遲遲不能進(jìn)入內(nèi)核主線。
utrace
utrace在07年的時(shí)候進(jìn)入內(nèi)核的視線(Introducing utrace),它的目的是完全取代ptrace在用戶態(tài)跟蹤的作用,utrace只是實(shí)現(xiàn)了一個(gè)在內(nèi)核中的engine,它提供了一個(gè)框架供更多的人基于它來實(shí)現(xiàn)對(duì)用戶程序的控制任務(wù)(Trace,Debug,user-mode-linux)。
utrace的體系架構(gòu)可以參考玩轉(zhuǎn) utrace。
utrace自07年在LWN中提出,然后迅速沉寂消失在視線之外,在09又重新希望進(jìn)入內(nèi)核主線中,當(dāng)時(shí)Red Hat和Fedora kernels其實(shí)已經(jīng)支持utrace很多年了。utrace進(jìn)入內(nèi)核最重要的問題是在內(nèi)核中沒有真正的用戶(以u(píng)trace為框架的實(shí)現(xiàn)),utrace如果只是一個(gè)engine就沒有進(jìn)入內(nèi)核的必要。
Frank Eigler(utrace開發(fā)者)提供了ftrace(下面會(huì)提到)基于utrace的實(shí)現(xiàn),但是內(nèi)核認(rèn)為這個(gè)實(shí)現(xiàn)只是個(gè)插件罷了,而另外一個(gè)utrace真正的用戶ptrace-over-utrace是被看做utrace進(jìn)入內(nèi)核的關(guān)鍵,但是有很多人以不成熟來反對(duì),雖然ptrace有大量的ugly code并且難以維護(hù)但是畢竟已經(jīng)存在這么多年了,取代ptrace是一個(gè)高風(fēng)險(xiǎn)的項(xiàng)目并且誰來做這個(gè)清理工作,如果不做清理工作兩者同時(shí)進(jìn)入內(nèi)核會(huì)帶來兩個(gè)ptrace實(shí)現(xiàn)帶來更多的問題,還有就是utrace并不是被所有架構(gòu)支持,如果ptrace使用utrace的實(shí)現(xiàn)而刪除自己的實(shí)現(xiàn)在其他架構(gòu)中(ARM和MIPS)就無法使用ptrace調(diào)用。并且ptrace-over-utrace如果想替代原來的ptrace實(shí)現(xiàn),必須需要有一些killer features(通過utrace的框架還是能實(shí)現(xiàn)很多的),Nesterov和McGrath這兩個(gè)ptrace的維護(hù)者站出來表示自己更愿意維護(hù)ptrace-over-utrace的方案,并且樂意去推出新的代碼。
問題之二是utrace會(huì)阻礙SystemTap進(jìn)入內(nèi)核(當(dāng)時(shí)有很多人期望SystemTap盡快進(jìn)入內(nèi)核),因?yàn)閡trace沒有一個(gè)系統(tǒng)調(diào)用而是內(nèi)核里的API(內(nèi)核接口會(huì)不穩(wěn)定),SystemTap利用了utrace的許多ABI來實(shí)現(xiàn)用戶態(tài)的跟蹤,如果utrace進(jìn)入內(nèi)核,SystemTap在主線外可能就導(dǎo)致在用戶態(tài)跟蹤上一團(tuán)糟(主線與非主線最重要的問題就是版本兼容性)并且需要尋找其他的方式。(PS:現(xiàn)在 systemtap 可以直接使用新的主流內(nèi)核中的 kprobes 和基于 inode 的uprobes 機(jī)制,不再依賴非主流的 utrace 補(bǔ)丁。同時(shí)它也可以直接使用主流內(nèi)核中的 perf 靜態(tài)探針 by agentzh)
在09年的Linux 2.6.30進(jìn)入主線失敗后,utrace就準(zhǔn)備好了長(zhǎng)期在主線外的命運(yùn),Red Hat不得不承擔(dān)起utrace的維護(hù)任務(wù)并且長(zhǎng)期在自己的內(nèi)核中保持。目前來說,utrace和SystemTap像是一對(duì)難兄難弟。
LTTng
LTTng是另外一個(gè)動(dòng)態(tài)跟蹤工具,它整合了內(nèi)核和用戶態(tài)跟蹤,對(duì)于大量的跟蹤事件流有非常高的性能,并且有一系列的分析和抓取工具。
對(duì)于目前的Linux內(nèi)核來說,LTTng只不過是眾多Tracing工具的一個(gè),它制造了太多重復(fù)的工作比如Rring Buffer(內(nèi)核中已經(jīng)有兩個(gè)Ring buffer被perf和ftrace使用),并且自己的系統(tǒng)調(diào)用接口(內(nèi)核已經(jīng)有此類的接口),增加LTTng意味著更混亂的Tracing ABI在內(nèi)核中。
相比較而言,LTTng進(jìn)入內(nèi)核比SystemTap和utrace更困難。
ftrace
相比前面的SystemTap、utrace和LTTng,ftrace就幸運(yùn)多了。ftrace是用來幫助開發(fā)者和系統(tǒng)設(shè)計(jì)者尋找系統(tǒng)負(fù)載的原因,它可以用來調(diào)試和分析內(nèi)核中的負(fù)載和性能原因。
ftrace之所以能順利進(jìn)入內(nèi)核中,主要還是因?yàn)樗浞掷昧藘?nèi)核中既有的設(shè)計(jì)和其他組件,它利用了debugfs、kprobes,uprobes等等,并且因?yàn)槠浜?jiǎn)單的靜態(tài)探針和安全性,ftrace的內(nèi)核之路順利而平坦。
Tracepoint
tracepoint是在內(nèi)核中預(yù)定義的一系列跟蹤點(diǎn)并且提供了hook讓使用者可以調(diào)用函數(shù)來進(jìn)行分析,tracepoint在有probe attach時(shí)會(huì)在每次執(zhí)行到tracepoint調(diào)用相應(yīng)的函數(shù)。
tracepoint在08年的時(shí)候被置入內(nèi)核中,ftrace也同樣使用tracepoint作為tracer使用。
kprobe
kprobes在Linux 2.6.9主線上實(shí)現(xiàn),它主要在內(nèi)核模塊中被使用,在模塊init 函數(shù)中安裝probe然后在exit時(shí)釋放。
更多的kprobe可以在Documents/kprobes.txt找到。
對(duì)于kprobe來說,更多的時(shí)候是被內(nèi)核模塊開發(fā)者使用。因?yàn)閗probe比較麻煩且相對(duì)于SystemTap這類工具來說,kprobe只有較少的使用空間。
uprobe
實(shí)現(xiàn)了動(dòng)態(tài)的介入用戶程序的運(yùn)行并且不打斷的收集信息,它的原理與kprobe類似,都是在探針函數(shù)的第一個(gè)字節(jié)用breakpoint指令替代,當(dāng)CPU運(yùn)行到breakpoint指令時(shí),uprobes得到通知并找到相應(yīng)uprobe來執(zhí)行對(duì)于的函數(shù)。
小結(jié)
目前Linux內(nèi)核上眾多跟蹤、性能工具的實(shí)現(xiàn)其實(shí)非?;靵y,像latencyTop、powertop、usbmon、blktrace都是好用的工具,但是每個(gè)工具都需要自己的hooks在內(nèi)核,這對(duì)于內(nèi)核而言是十分蛋疼的事情。而在Solaris中,powertop這類是在Dtrace之上實(shí)現(xiàn)的,不需要改變內(nèi)核。
從Linux性能工具的發(fā)展可以看到,upstream kernel和商用kernel,其他系統(tǒng)(Solaris)的博弈和權(quán)衡是十分激烈的。對(duì)于Linux社區(qū)而言,Linus對(duì)于代碼的把控是十分必要的,在11年kernel summit之后,開發(fā)者已經(jīng)普遍贊成收斂系統(tǒng)調(diào)用的增加,這對(duì)于LTTng,utrace的進(jìn)入內(nèi)核希望更小了。