1. 程式人生 > >系統級效能分析工具--Systemtap

系統級效能分析工具--Systemtap

  SystemTap 是一款診斷Linux系統性能的工具,可以跟蹤核心以及使用者態程式中的任意函式、syscall、語句甚至指令,可以用來動態地收集除錯和效能資訊的工具,不需要我們重新編譯、重啟核心。缺點:使用者需要自己編輯指令碼測試檔案。

假如現在有這麼一個需求:需要獲取正在執行的 Linux 系統的資訊,如我想知道系統什麼時候發生系統呼叫,發生的是什麼系統呼叫等這些資訊,有什麼解決方案呢?

  • 最原始的方法是,找到核心系統呼叫的程式碼,加上我們需要獲得資訊的程式碼、重新編譯核心、安裝、選擇我們新編譯的核心重啟。這種做法對於核心開發人員簡直是夢魘,因為一遍做下來至少得需要1個多小時,不僅破壞了原有核心程式碼,而且如果換了一個需求又得重新做一遍上面的工作。所以,這種除錯核心的方法效率是極其底下的。
  • 之後核心引入了一種Kprobe機制,可以用來動態地收集除錯和效能資訊的工具,是一種非破壞性的工具,使用者可以用它跟蹤執行中核心任何函式或執行的指令等。相比之前的做法已經有了質的提高了,但Kprobe並沒有提供一種易用的框架,使用者需要自己去寫模組,然後安裝,對使用者的要求還是蠻高的。
  • systemtap 是利用Kprobe 提供的API來實現動態地監控和跟蹤執行中的Linux核心的工具,相比Kprobe,systemtap更加簡單,提供給使用者簡單的命令列介面,以及編寫核心指令的指令碼語言。對於開發人員,systemtap是一款難得的工具。

systemtap 的安裝

安裝核心除錯所需要的包

yum -y install kernel-devel-2.6.32-642.3.1.el6.x86_64

yum -y install kernel-debuginfo-2.6.32-642.3.1.el6.x86_64

yum -y install kernel-debuginfo-common-x86_64-2.6.32-642.3.1.el6.x86_64

安裝SystemTap並配置指令碼

yum -y install systemtap

systemtap 測試示例

安裝完systemtap之後,我們需要測試一下systemtap是否能正確執行:

示例一:列印hello systemtap

以root使用者或者具有sudo許可權的使用者執行以下命令:

$stap -ve 'probe begin { log("hello systemtap!") exit() }'

如果安裝正確,會得到如下類似的輸出結果:

Pass 1: parsed user script and 96 library script(s) using 55100virt/26224res/2076shr/25172data kb, in 120usr/0sys/119real ms.
Pass 2: analyzed script: 1 probe(s), 2 function(s), 0 embed(s), 0 global(s) using 55496virt/27016res/2172shr/25568data kb, in 0usr/0sys/4real ms.
Pass 3: translated to C into "/tmp/stapYqNuF9/stap_e2d1c1c9962c809ee9477018c642b661_939_src.c" using 55624virt/27380res/2488shr/25696data kb, in 0usr/0sys/0real ms.
Pass 4: compiled C into "stap_e2d1c1c9962c809ee9477018c642b661_939.ko" in 1230usr/160sys/1600real ms.
Pass 5: starting run.
hello systemtap!
Pass 5: run completed in 0usr/10sys/332real ms.

示例二:輸出4s內所有open系統呼叫的資訊

建立systemtap指令碼檔案test2.stp:

#!/usr/bin/stap

probe begin 
{
    log("begin to probe")
}

probe syscall.open
{
    printf ("%s(%d) open (%s)\n", execname(), pid(), argstr)
}

probe timer.ms(4000) # after 4 seconds
{
    exit ()
}

probe end
{
    log("end to probe")
}

將該指令碼新增可執行的許可權 chmod +x test2.stp ,使用./test2.stp 執行該指令碼,即可輸出4s內所有open系統呼叫的資訊,列印格式為:程序名(程序號)開啟什麼檔案。 大家可以自行去測試,如果兩個示例都能正確執行,基本上算是安裝成功了!

systemtap 工作原理

systemtap 的核心思想是定義一個事件(event),以及給出處理該事件的控制代碼(Handler)。當一個特定的事件發生時,核心執行該處理控制代碼,就像快速呼叫一個子函式一樣,處理完之後恢復到核心原始狀態。這裡有兩個概念:

  • 事件(Event):systemtap 定義了很多種事件,例如進入或退出某個核心函式、定時器時間到、整個systemtap會話啟動或退出等等。
  • 控制代碼(Handler):就是一些指令碼語句,描述了當事件發生時要完成的工作,通常是從事件的上下文提取資料,將它們存入內部變數中,或者打印出來。

Systemtap 工作原理是通過將指令碼語句翻譯成C語句,編譯成核心模組。模組載入之後,將所有探測的事件以鉤子的方式掛到核心上,當任何處理器上的某個事件發生時,相應鉤子上控制代碼就會被執行。最後,當systemtap會話結束之後,鉤子從核心上取下,移除模組。整個過程用一個命令 stap 就可以完成。 上面只是簡單的原理,更多背後的機理參考網上資料和相應的論文。 圖 systemtap 處理流程