8.0 概述
本章介紹一些在Linux系統(tǒng)上可用的實(shí)用程序,它們能夠加強(qiáng)性能工具的有效性和可用性。實(shí)用工具本身不是性能工具,但是當(dāng)它們與性能工具一起使用時(shí),它們可以幫助完成如下功能:自動(dòng)執(zhí)行繁瑣的任務(wù)、分析性能統(tǒng)計(jì)數(shù)據(jù),以及創(chuàng)建性能工具友好的應(yīng)用程序。
閱讀本章后,你將能夠:
- 定期顯示并收集性能數(shù)據(jù)(bash、watch)。
- 記錄性能調(diào)查過程中所有的命令以及顯示的輸出(tee、script)。
- 導(dǎo)入、分析性能數(shù)據(jù)并將其圖形化(gnumeric)。
- 確定應(yīng)用程序使用的庫(kù)(ldd)。
- 確定鏈接庫(kù)中有哪些函數(shù)(objdump)。
- 研究應(yīng)用程序的運(yùn)行時(shí)特征(gdb)。
- 創(chuàng)建性能工具/調(diào)試友好的應(yīng)用程序(gcc)。
8.1性能工具助手
Linux有著豐富的工具,這些工具一起使用比起單個(gè)使用之和的功能更強(qiáng)大。性能工具也是一樣的,雖然可以單獨(dú)使用,但是它們與其他Linux工具結(jié)合起來(lái)就能夠顯著提升其有效性和易用性。
8.1.1自動(dòng)執(zhí)行和記錄命令
如同前面章節(jié)所述,性能調(diào)查中最有價(jià)值的步驟之一就是保存在調(diào)查過程中發(fā)出的命令和產(chǎn)生的結(jié)果。這使得你可以在之后對(duì)它們進(jìn)行回顧并尋求新的見解。為了幫助實(shí)現(xiàn)這個(gè)目的,Linux提供了兩個(gè)命令:tee和script,前者能將工具的輸出保存為文件,后者能記錄每一個(gè)按鍵和屏幕上的每一個(gè)輸出。這些信息可以保存下來(lái),便于之后查看或者創(chuàng)建腳本來(lái)自動(dòng)執(zhí)行測(cè)試。
自動(dòng)執(zhí)行命令很重要,因?yàn)樗梢詼p少出錯(cuò)的機(jī)會(huì),使你在思考問題時(shí)不需記住所有的細(xì)節(jié)。在你一次性鍵入又長(zhǎng)又復(fù)雜的命令行之后,bash shell和watch命令都可以讓你周期性地自動(dòng)執(zhí)行這些命令。在你保證了命令行的正確性后,bash和watch能夠周期性地自動(dòng)執(zhí)行它們,不需要再次鍵入。
8.1.2性能統(tǒng)計(jì)信息的繪圖與分析
除了記錄與自動(dòng)化工具之外,Linux還提供了強(qiáng)大的分析工具幫助你理解性能統(tǒng)計(jì)數(shù)據(jù)的含義。盡管大多數(shù)性能工具可以把性能統(tǒng)計(jì)數(shù)據(jù)輸出為文本,但是想要發(fā)現(xiàn)其中的模式和隨時(shí)間變化的趨勢(shì)并不總是件容易的事兒。Linux提供的gnumeric電子表格很強(qiáng)大,它可以對(duì)性能數(shù)據(jù)進(jìn)行導(dǎo)入、分析和繪圖。當(dāng)你繪制數(shù)據(jù)圖時(shí),性能問題的原因可能會(huì)變得明晰,或者至少能揭示調(diào)查的新角度。
8.1.3調(diào)查應(yīng)用程序使用的庫(kù)
還有一些Linux的工具能使你確定應(yīng)用程序使用了哪些庫(kù),以及顯示給定庫(kù)提供的所有函數(shù)。ldd命令給出一個(gè)特定應(yīng)用程序使用的全部共享庫(kù)的列表。在你想要跟蹤被應(yīng)用程序使用的庫(kù)的數(shù)量和位置時(shí),這個(gè)命令很有用。Linux中還有一個(gè)命令objdump,它可以在指定庫(kù)或應(yīng)用程序中搜索并顯示其提供的全部函數(shù)。ltrace只能給出一個(gè)應(yīng)用程序調(diào)用函數(shù)的名稱,但是結(jié)合命令ldd和objdump,你就能夠利用ltrace的輸出來(lái)確定指定函數(shù)屬于哪個(gè)庫(kù)。
8.1.4創(chuàng)建和調(diào)試應(yīng)用程序
最后,Linux還為你提供了能夠創(chuàng)建性能工具友好型應(yīng)用程序的工具,以及交互式調(diào)試和調(diào)查運(yùn)行中應(yīng)用程序?qū)傩缘墓ぞ摺NU編譯器集(gcc)可以在應(yīng)用程序中插入調(diào)試信息,以幫助oprofile找出某個(gè)具體性能問題對(duì)應(yīng)的代碼行和源文件。此外,GNU調(diào)試器(gdb)還可以用來(lái)查找被各種性能工具默認(rèn)不可得的應(yīng)用程序的運(yùn)行時(shí)信息。
8.2 工具
本節(jié)討論的工具一起使用時(shí),可以極大地提高前面章節(jié)介紹的性能工具的有效性和易用性。
8.2.1 bash
bash是默認(rèn)的Linux命令行shell,在你每次與Linux命令行交互時(shí),最有可能使用它。bash通常有一個(gè)功能強(qiáng)大的腳本語(yǔ)言來(lái)創(chuàng)建shell腳本。不過這個(gè)腳本語(yǔ)言也可以從命令行調(diào)用,從而使你在性能調(diào)查過程中,能輕松地將一些比較繁瑣的任務(wù)進(jìn)行自動(dòng)化。
8.2.1.1性能相關(guān)的選項(xiàng)
bash有一組命令可以一起使用,來(lái)周期性地運(yùn)行特定命令。大多數(shù)Linux用戶都把bash作為默認(rèn)的shell,因此,只要登錄到一臺(tái)機(jī)器或打開一個(gè)終端就會(huì)出現(xiàn)bash提示。如果你沒有使用bash,也可以鍵入bash來(lái)調(diào)用它。
有了bash命令提示符后,你可以輸入一系列的bash腳本命令來(lái)自動(dòng)連續(xù)地執(zhí)行特定命令。在使用特定命令周期性提取性能統(tǒng)計(jì)數(shù)據(jù)的情況下,這個(gè)功能非常有用。表8-1給出了這些腳本選項(xiàng)。
bash極其靈活,它記錄在bash手冊(cè)中。雖然bash非常復(fù)雜,但是在使用它之前并不需要完全掌握它。
8.2.1.2 用法示例
雖然有些性能工具,如vmstat和sar,能周期性地更新性能統(tǒng)計(jì)信息,但是其他的命令,比如ps和ifconfig則不能。bash可以調(diào)用諸如ps或ifconfig命令來(lái)周期性地顯示它們的統(tǒng)計(jì)數(shù)據(jù)。例如,在清單8.1中,我們要求bash在條件為true時(shí)執(zhí)行while循環(huán)。由于true命令總是為真,因此這個(gè)while循環(huán)永遠(yuǎn)都不會(huì)結(jié)束。接著,在do命令后啟動(dòng)每次迭代之后都要執(zhí)行的命令,這些命令要求bash休眠1秒鐘,然后運(yùn)行ifconfig來(lái)抽取eth0控制器的性能信息。不過,我們只關(guān)心接收數(shù)據(jù)包,因此,我們用grep搜索并顯示字符串為“RX packets”的ifconfig輸出。最后,執(zhí)行done命令來(lái)告訴bash循環(huán)完成。由于true命令總是返回真,所以,該循環(huán)將一直執(zhí)行直到用組合鍵終止它。
利用清單8.1的bash腳本,可以查看到按秒更新的網(wǎng)絡(luò)性能統(tǒng)計(jì)信息。同樣的循環(huán)還可以用于監(jiān)控其他的事件,只要將ifconfig命令修改為其他的命令即可,而通過修改休眠數(shù)值也能夠改變更新時(shí)間間隔。這個(gè)簡(jiǎn)單的循環(huán)容易直接在命令行中鍵入,并且能夠自動(dòng)顯示任何你感興趣的性能統(tǒng)計(jì)數(shù)據(jù)。
8.2.2 tee
tee是一個(gè)簡(jiǎn)單的命令,可以將命令的標(biāo)準(zhǔn)輸出保存為文件并同時(shí)進(jìn)行顯示。在想要保存并同時(shí)查看性能工具輸出的時(shí)候,tee是很有幫助的。比如,正在監(jiān)控一個(gè)實(shí)時(shí)系統(tǒng)的性能統(tǒng)計(jì)信息的同時(shí),保存這些數(shù)據(jù)以備將來(lái)對(duì)它們進(jìn)行分析。
8.2.2.1性能相關(guān)的選項(xiàng)
tee的調(diào)用命令行如下:
I tee [-a] [file]
tee獲取由提供的輸出,在將其保存到指定文件的同時(shí)也顯示到標(biāo)準(zhǔn)輸出設(shè)備。如果特別指定了-a選項(xiàng),則tee會(huì)將輸出添加到文件上,而不是覆蓋文件。
8.2.2.2 用法示例
清單8.2展示了用tee來(lái)記錄vmstat的輸出。如你所見,tee顯示了vmstat生成的輸出,并同時(shí)將其保存到文件/tmp/vmstat_out。保存vmstat的輸出能讓我們?cè)趯?lái)的時(shí)間里對(duì)性能數(shù)據(jù)進(jìn)行分析或繪圖。
tee命令很簡(jiǎn)單,但由于它能輕松地記錄指定性能工具的輸出,因此它的能力也是非常強(qiáng)大的。
8.2.3 script
script命令用于將一個(gè)shell會(huì)話過程中產(chǎn)生的全部輸入和輸出保存為文本文件。這個(gè)文本文件在將來(lái)既可以用來(lái)重現(xiàn)被執(zhí)行的命令也可以用來(lái)查看結(jié)果。在調(diào)查性能問題時(shí),準(zhǔn)確記錄被執(zhí)行命令是很有用的,因?yàn)槟憧梢栽谥蟮臅r(shí)間里查看執(zhí)行過的測(cè)試。擁有被執(zhí)行命令的記錄就意味著在調(diào)查不同的問題時(shí),你還可以簡(jiǎn)單地對(duì)命令行進(jìn)行剪切和粘貼。此外,記錄性能結(jié)果也是很有幫助的,這樣你就可以在將來(lái)查看這些記錄以尋求發(fā)現(xiàn)和解決問題的新視角。
8.2.3.1性能相關(guān)的選項(xiàng)
script是一個(gè)相對(duì)簡(jiǎn)單的命令。在執(zhí)行的時(shí)候,它會(huì)啟動(dòng)一個(gè)新的shell,并記錄下這個(gè)shell存續(xù)期間所有的鍵盤動(dòng)作和輸入,以及生成的輸出,并將它們保存到文本文件。script 的調(diào)用命令行如下所示:
script [-a] [-t] [file]
默認(rèn)情況下,script把所有的輸出都放到名為typescript的文件中,除非你特別指定其他的文件。表8-2給出了一些script的命令行選項(xiàng)。
提醒:script字面上的意思是捕捉發(fā)送到屏幕的每一種類型的輸出。但是,如果有彩色或加粗的輸出,就會(huì)在輸出文件中顯示為esc字符。這些字符會(huì)明顯讓輸出變得混亂,因此一般不怎么有用。不過,如果將TERM環(huán)境變量設(shè)置為dumb(在基于csh的shell中用setenv TERM dumb,在基于sh的shell中用export TERM=dumb),應(yīng)用程序就不會(huì)輸出轉(zhuǎn)義字符。這就使得輸出具有更好的可讀性。
此外,script提供的計(jì)時(shí)信息也會(huì)擾亂輸出。雖然自動(dòng)生成計(jì)時(shí)信息是有用的,但是更方便的做法不是使用script的計(jì)時(shí),而是直接用前面章節(jié)介紹的time命令來(lái)對(duì)重要命令進(jìn)行計(jì)時(shí)。
8.2.3.2 用法示例
如前所述,如果將終端設(shè)置為dumb,會(huì)得到可讀性更好的script輸出。其實(shí)現(xiàn)方法是使用如下命令行:
[ezoltewintermute manuscript]$ export TERM=dumb
然后,正式啟動(dòng)script命令。清單8.3顯示的是用輸出文件ps_output啟動(dòng)的script。script會(huì)持續(xù)記錄會(huì)話,直到用exit命令或按下組合鍵退出該shell。
接下來(lái),在清單8.4中可以查看由script記錄下的輸出。如你所見,其中包含了所有的命令以及生成的全部輸出。
script是一個(gè)非常有用的命令,用來(lái)記錄會(huì)話過程中所有的交互。與現(xiàn)代硬盤容量相比,script產(chǎn)生的文件非常小。記錄性能調(diào)查會(huì)話,并將其保存下來(lái)以備將來(lái)查看一直都是一個(gè)很棒的主意。往最壞的情況考慮,它會(huì)浪費(fèi)一點(diǎn)點(diǎn)精力和磁盤空間來(lái)記錄會(huì)話。往最好的情況考慮,被保存的會(huì)話可以在之后的時(shí)間查看,而不需要重新運(yùn)行該會(huì)話被記錄下的命令。
8.2.4 watch
默認(rèn)情況下,watch命令會(huì)每秒運(yùn)行一條命令并將其輸出顯示到屏幕上。與那些不能周期性地顯示更新結(jié)果的性能工具一起工作時(shí),watch能發(fā)揮其作用。比如,有些工具,如ifconfig和ps,顯示的是當(dāng)前性能統(tǒng)計(jì)數(shù)據(jù),然后退出。由于watch能周期性地執(zhí)行命令并顯示其輸出,因此,通過觀看屏幕就可以發(fā)現(xiàn)哪些統(tǒng)計(jì)數(shù)據(jù)發(fā)生了變化,以及它們的變化速率。
8.2.4.1性能相關(guān)的選項(xiàng)
watch用如下命令行調(diào)用:
watch [-d [=cumulative] ] [-n sec]
如果調(diào)用的時(shí)候不帶參數(shù),watch只會(huì)按秒顯示給定命令的輸出,直到你中斷這個(gè)過程。默認(rèn)輸出通常很難發(fā)現(xiàn)一屏信息與另一屏信息的差異,因此,watch提供了選項(xiàng)來(lái)突出顯示每個(gè)輸出之間的不同。這樣更容易發(fā)現(xiàn)每個(gè)采樣之間的輸出差異。表8-3對(duì)watch可接受命令行選項(xiàng)進(jìn)行了說明。
watch是一種強(qiáng)大的工具,用于查看性能統(tǒng)計(jì)數(shù)據(jù)如何隨時(shí)間變化。它并不復(fù)雜,但是卻能很好地完成自己的工作。它真正填補(bǔ)了使用某些性能工具所造成的空白,這些工具無(wú)法周期性地顯示已更新的輸出。在使用這些工具時(shí),你可以用窗口形式運(yùn)行watch,通過定期查看該窗口來(lái)了解統(tǒng)計(jì)信息是如何變化的。
8.2.4.2用法示例
清單8.5中的第一個(gè)例子展示了與ps命令一起使用的watch。我們要求ps給出每個(gè)進(jìn)程產(chǎn)生的一般故障的數(shù)量。watch每10秒清除屏幕,并更新該信息。請(qǐng)注意,可能需要為你要求執(zhí)行的命令加上引號(hào),這樣,watch就不會(huì)將你想要執(zhí)行的命令的選項(xiàng)與它自身的選項(xiàng)搞混。
watch作為一種工具,其基本功能可以很容易地編寫為簡(jiǎn)單的shell腳本。但是,watch 比使用shell腳本更簡(jiǎn)單,因?yàn)樗鼛缀蹩偸强捎玫?,并且能正確地工作。別忘了,有些性能工具,如ifconfig或ps只能一次性地顯示統(tǒng)計(jì)數(shù)據(jù),而watch卻能很容易地跟蹤(只需看上一眼)統(tǒng)計(jì)數(shù)據(jù)的變化。
8.2.5gnumeric
在進(jìn)行性能問題調(diào)查時(shí),性能工具常常會(huì)生成龐大的性能統(tǒng)計(jì)數(shù)據(jù)。有些時(shí)候,梳理這些數(shù)據(jù)并從中找出能夠表明系統(tǒng)運(yùn)行情況的趨勢(shì)與模式就成了一個(gè)問題。通常電子表格,尤其是gnumeric,能夠從三個(gè)不同的方面使得這個(gè)任務(wù)變得容易實(shí)現(xiàn)。首先,gnumeric提供了內(nèi)置函數(shù),比如求最大值、最小值、平均值和標(biāo)準(zhǔn)偏差,這就使你能對(duì)性能數(shù)據(jù)進(jìn)行數(shù)值分析。其次,gnumeric提供了靈活的方式來(lái)導(dǎo)入許多性能工具常用輸出的表格文本數(shù)據(jù)。最后,gnumeric還有一個(gè)強(qiáng)大的繪圖工具,可以將性能工具生成的性能數(shù)據(jù)可視化。這不但對(duì)于探尋較長(zhǎng)時(shí)間內(nèi)的數(shù)據(jù)趨勢(shì)是極有價(jià)值的,而且對(duì)于尋找不同類型數(shù)據(jù)之間的相關(guān)性(比如磁盤I/O與CPU使用量之間的相關(guān)性)也是相當(dāng)有用的。通常,要從文本輸出中找出模式是比較困難的,但對(duì)圖形來(lái)說,系統(tǒng)行為就會(huì)顯得更加清晰。其他的電子表格,如OpenOffice的oocalc,也可以使用,不過gnumeric強(qiáng)大的文本導(dǎo)入器和繪圖工具使得它成為最容易被使用的工具。
8.2.5.1性能相關(guān)的選項(xiàng)
使用電子表格幫助實(shí)現(xiàn)性能分析,只需完成以下步驟:
- 將性能數(shù)據(jù)保存到文本文件。
- 將文本文件導(dǎo)入到gnumeric。
- 分析數(shù)據(jù)或用數(shù)據(jù)繪圖。
gnumeric可以生成多種不同類型的圖形,并且提供了多種不同的函數(shù)實(shí)現(xiàn)數(shù)據(jù)分析。了解gnumeric的強(qiáng)大功能和靈活性的最好方法就是加載一些數(shù)據(jù)進(jìn)行實(shí)驗(yàn)。
8.2.5.2 用法示例
要展示gnumeric的實(shí)用性,首先必須生成用于繪圖和分析的性能數(shù)據(jù)。清單8.6要求vmstat生成100秒的輸出,并將該信息保存到文本文件vmstat_output中。數(shù)據(jù)將會(huì)被加載到gnumeric。-n選項(xiàng)表示vmstat只顯示頭信息一次(而不是每屏信息都顯示)。
接下來(lái),用如下命令啟動(dòng)gnumeric:
[ezoltenohs ezoltjs gnumeric &
這會(huì)打開一個(gè)空白電子表格用于導(dǎo)入vmstat數(shù)據(jù)。
在gnumeric中選擇File>Open,彈出一個(gè)對(duì)話框(圖中未顯示)用于選擇打開的文件及該文件的類型。我們選擇Text Import(Configurable)作為文件類型,然后通過一系列的向?qū)?duì)話框來(lái)選擇將vmstat_output文件的哪一列映射到電子表格的哪一列。對(duì)vmstat而言,最好從第二行文本開始導(dǎo)入,因?yàn)榈诙邪肆忻Q以及每一列適合的大小。此外,為導(dǎo)入數(shù)據(jù)選擇Fixed-Width也是很有用的,其原因是vmstat就是這樣輸出數(shù)據(jù)的。在成功導(dǎo)入數(shù)據(jù)后,我們就會(huì)看到如圖8-1所示的電子表格。
接下來(lái),利用導(dǎo)入的數(shù)據(jù)繪圖。在圖8-2中,我們用不同的CPU使用情況(us、sys、id、wa)創(chuàng)建了一個(gè)疊式圖。由于這些數(shù)據(jù)的總和始終為100%(或接近該值),因此,每次都能看出哪種狀態(tài)處于主導(dǎo)地位。本例中,系統(tǒng)在大部分時(shí)間都是空閑的,不過在圖中1/4 的部分出現(xiàn)了大量的等待時(shí)間。
圖形是查看一個(gè)測(cè)試單次運(yùn)行時(shí),其性能統(tǒng)計(jì)數(shù)據(jù)隨時(shí)間變化情況的有力手段。同時(shí),對(duì)于發(fā)現(xiàn)不同運(yùn)行的對(duì)比差異也是很有幫助的。用不同運(yùn)行得到的數(shù)據(jù)繪圖時(shí),要確保每個(gè)圖使用的比例是相同的,這能讓數(shù)據(jù)的比較對(duì)照更加容易。
gnumeric是一種輕量級(jí)的應(yīng)用程序,它使你能快速簡(jiǎn)便地導(dǎo)入、繪圖/分析大量的性能數(shù)據(jù)。它是一種很棒的工具,通過處理性能數(shù)據(jù)來(lái)探尋是否出現(xiàn)了任何有趣的特性。
8.2.6 ldd
ldd可以被用來(lái)顯示特定的二進(jìn)制文件依賴的是哪個(gè)庫(kù)。ldd有助于跟蹤一個(gè)應(yīng)用程序可能使用的庫(kù)函數(shù)的位置。通過給出應(yīng)用程序正在使用的所有庫(kù),就可以對(duì)它們進(jìn)行搜索,找出包含給定函數(shù)的庫(kù)。
8.2.6.1性能相關(guān)的選項(xiàng)
ldd用如下命令行調(diào)用:
ldd
接著ldd會(huì)列出該二進(jìn)制文件需要的所有庫(kù),以及系統(tǒng)中有哪些文件能實(shí)現(xiàn)這些需求。
8.2.6.2用法示例
清單8.7展示的是1dd用在二進(jìn)制文件ls上。在這個(gè)特定的例子中,我們可以發(fā)現(xiàn)ls使用了如下這些庫(kù):linux-gate.so.1,librt.so.1,libaclso.1,libselinux.so.1,libc.so.6,libpthread.so.0,ld-linux.so.2和libattr.so.1。
ldd是一個(gè)相對(duì)簡(jiǎn)單的工具,但對(duì)于試圖追蹤應(yīng)用程序使用了哪些庫(kù)以及這些庫(kù)在系統(tǒng)中的位置來(lái)說,它具有極大的價(jià)值。
8.2.7 objdump
對(duì)于分析二進(jìn)制文件和庫(kù)的各個(gè)方面來(lái)說,objdump是一種復(fù)雜而強(qiáng)大的工具。盡管它有許多其他的功能,它可以被用來(lái)確定給定的庫(kù)提供了哪些函數(shù)。
8.2.7.1 性能相關(guān)的選項(xiàng)
objdump用如下命令行調(diào)用:
objdump -T
如果調(diào)用的時(shí)候使用了-T選項(xiàng),則它將顯示該庫(kù)/二進(jìn)制文件所依賴或提供的全部符號(hào)。這些符號(hào)可以是數(shù)據(jù)結(jié)構(gòu),也可以是函數(shù)。包含.text的每一行objdump輸出都是該二進(jìn)制文件提供的一個(gè)函數(shù)。
8.2.7.2 用法示例
清單8.8展示的是objdump用于分析庫(kù)gtk。因?yàn)槲覀兏信d趣的只有l(wèi)ibgtk.so提供的符號(hào),所以用fgrep對(duì)輸出進(jìn)行選擇,僅輸出那些包含.text的行。本例中,我們可以看到libgtk.so提供的一些函數(shù),包括gtk_arg_values_equal、gtk_tooltips_set_colors和gtk_viewport_set_hadjustment。
在使用性能工具時(shí),它們會(huì)顯示一個(gè)應(yīng)用程序調(diào)用的庫(kù)函數(shù)(而不是庫(kù)本身),objdump 能幫助找到每個(gè)函數(shù)所在的共享庫(kù)。
8.2.8 GNU調(diào)試器(gdb)
gdb是一個(gè)很棒的應(yīng)用程序調(diào)試器,它可以幫助調(diào)查一個(gè)正在運(yùn)行的應(yīng)用程序的多個(gè)不同方面。gdb具備三個(gè)特性使得它對(duì)診斷性能問題來(lái)說非常有價(jià)值。第一,gdb可以附加到當(dāng)前正在運(yùn)行的進(jìn)程。第二,gdb可以展示該進(jìn)程的回溯,即顯示當(dāng)前源代碼行和調(diào)用樹。附加到進(jìn)程并抽取其回溯可以迅速找出一些比較明顯的性能問題。但是,如果應(yīng)用程序不是卡在單點(diǎn)上,那么使用gdb就難以進(jìn)行問題診斷,此時(shí),系統(tǒng)級(jí)的分析器,如oprofile,將會(huì)是一個(gè)更好的選擇。第三,gdb可以將虛擬地址映射回特定的函數(shù)。與性能工具相比,gdb更擅長(zhǎng)計(jì)算虛擬地址的位置。例如,如果oprofile給出了事件發(fā)生的虛擬地址而非函數(shù)名,那么gdb就可以計(jì)算出該地址的函數(shù)。
8.2.8.1性能相關(guān)的選項(xiàng)
gdb用如下命令行調(diào)用,其中,pid是指gdb將要附加的進(jìn)程:
gdb -p pid
gdb附加到該進(jìn)程后,它就進(jìn)入到交互模式,這時(shí)就可以檢查給定進(jìn)程的當(dāng)前執(zhí)行位置和運(yùn)行時(shí)變量。表8-4對(duì)其中的一條命令進(jìn)行了說明,可用其檢查正在運(yùn)行的進(jìn)程。
gdb還有很多命令行選項(xiàng)和運(yùn)行時(shí)控件,它們更適合于調(diào)試而不是性能調(diào)查。獲取更多信息請(qǐng)參見gdb手冊(cè)頁(yè)或在gdb提示中鍵入help。
8.2.8.2用法示例
想要研究gdb是如何工作的,可以先在一個(gè)簡(jiǎn)單的測(cè)試應(yīng)用程序上演示它。清單8.9中的程序在main中只調(diào)用了函數(shù)a(),并陷入了一個(gè)無(wú)限循環(huán)。這個(gè)程序不會(huì)結(jié)束,因此當(dāng)我們將gdb附加上去后,它將會(huì)一直執(zhí)行函數(shù)a()的無(wú)限循環(huán)。
清單8.10啟動(dòng)應(yīng)用程序并用gdb附加到它的pid。我們要求gdb產(chǎn)生一個(gè)回溯,以便展示當(dāng)前正在執(zhí)行的究竟是哪條代碼,以及哪組函數(shù)調(diào)用會(huì)導(dǎo)致當(dāng)前的位置。如同預(yù)期的,gdb顯示出正在執(zhí)行的是無(wú)限循環(huán)a(),它是由main()調(diào)用的。
最后,在清單8.11中,我們要求gdb給出虛擬地址0x0804832F的位置,而gdb顯示該地址是函數(shù)main的一部分。
gdb是一個(gè)極其強(qiáng)大的調(diào)試器,可以幫助調(diào)查性能問題。如果你想要知道特定代碼路徑發(fā)生的確切原因,那么gdb甚至在性能問題已經(jīng)確定之后也能夠發(fā)揮作用。
8.2.9 gcc(GNU編譯器套件)
gcc是Linux系統(tǒng)中最流行的編譯器。與所有的編譯器一樣,gcc需要源代碼(如C、C++或Objective-C)生成二進(jìn)制代碼。它提供了多個(gè)選項(xiàng)不僅可以對(duì)得到的二進(jìn)制代碼進(jìn)行優(yōu)化,還能讓應(yīng)用程序的性能跟蹤變得更容易。本書不涉及gcc性能優(yōu)化的詳細(xì)內(nèi)容,但是如果想要提高應(yīng)用程序的性能,你就應(yīng)該研究一下這些內(nèi)容。gcc提供的性能優(yōu)化選項(xiàng)通過多種優(yōu)化來(lái)調(diào)整已編譯的二進(jìn)制文件的性能,這些優(yōu)化包括:架構(gòu)通用優(yōu)化(使用-01、-02、-03),特定架構(gòu)優(yōu)化(-march和-mcpu),以及基于反饋的優(yōu)化(使用-fprofile -arcs和-fbranch-probabilities)。更多的優(yōu)化選項(xiàng)詳情請(qǐng)參閱gcc手冊(cè)頁(yè)。
8.2.9.1性能相關(guān)的選項(xiàng)
gcc最基本的調(diào)用格式如下所示:
gcc [-g level] [-pg] -0 prog_name source.c
gcc有數(shù)量龐大的選項(xiàng)來(lái)影響它對(duì)應(yīng)用程序的編譯。如果你有勇氣的話,可以到gcc手冊(cè)頁(yè)上查閱它們。表8-5給出了有助于性能調(diào)查的具體選項(xiàng)。
許多性能調(diào)查工具,如oprofile,需要用調(diào)試信息編譯應(yīng)用程序,以便將性能信息映射回特定的應(yīng)用程序源代碼行。如果沒有調(diào)試信息,它們一般也還是可以工作,但是如果啟動(dòng)調(diào)試,那么它們將會(huì)提供更豐富的信息。應(yīng)用程序分析的更多信息參見前面的章節(jié)。
8.2.9.2用法示例
理解gcc可以提供的調(diào)試信息類型的最好方法可能就是看一個(gè)簡(jiǎn)單的例子。清單8.12 中有一個(gè)C應(yīng)用程序的源代碼deep.c,該程序僅調(diào)用了一組函數(shù),然后根據(jù)傳遞的數(shù)字輸出一定數(shù)量的字符串“hi”。程序的main函數(shù)調(diào)用函數(shù)a(),函數(shù)a()調(diào)用函數(shù)b(),然后輸出“hi”。
首先,如清單8.13所示,編譯該程序時(shí)不帶任何調(diào)試信息。在調(diào)試器中啟動(dòng)該程序,在函數(shù)b()上添加一個(gè)斷點(diǎn)。當(dāng)程序運(yùn)行時(shí),它會(huì)在函數(shù)b()處暫停,并請(qǐng)求回溯。gdb可以弄清楚回溯,但是它并不知道函數(shù)之間傳遞了什么樣的值或者函數(shù)存在于原始源代碼文件中的什么位置。
清單8.14啟動(dòng)調(diào)試信息對(duì)同樣的應(yīng)用程序進(jìn)行編譯?,F(xiàn)在,當(dāng)運(yùn)行g(shù)db并產(chǎn)生回溯時(shí),我們可以看到每個(gè)函數(shù)調(diào)用傳遞的數(shù)值,以及特定代碼行所駐留的準(zhǔn)確的源代碼行。
調(diào)試信息會(huì)顯著增加gcc最終生成的可執(zhí)行文件的大小。但是,在追蹤性能問題時(shí),由其提供的信息卻是無(wú)價(jià)的。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-723223.html
8.3 本章小結(jié)
本章給出了對(duì)調(diào)查性能問題有用的各種Linux實(shí)用工具的集合。首先介紹的工具如bash、watch、tee和script能自動(dòng)顯示和收集性能數(shù)據(jù)。之后介紹了gnumeric,該工具可以對(duì)基于文本的性能工具所得到的結(jié)果進(jìn)行繪圖和分析。之后研究了ldd和objdump,它們可用于發(fā)現(xiàn)一個(gè)函數(shù)屬于哪個(gè)庫(kù)。接著本章描述了gdb,它能夠被用來(lái)調(diào)查當(dāng)前正在運(yùn)行的應(yīng)用程序的執(zhí)行和運(yùn)行時(shí)信息。最后,本章給出了gcc,該工具可生成帶符號(hào)調(diào)試信息的二進(jìn)制文件,這可以幫助其他性能工具,如oprofile,將事件映射回一個(gè)特定的源代碼行。
在之后的章節(jié)中,我們將集合迄今為止提出的所有工具,以解決一些現(xiàn)實(shí)的性能問題。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-723223.html
到了這里,關(guān)于Linux性能優(yōu)化--實(shí)用工具:性能工具助手的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!