systemtap是內核開發者必需要掌握的一個工具,本文我將簡單介紹一下此工具,後續將會有系列文章介紹systemtap的用法。html
假如如今有這麼一個需求:須要獲取正在運行的 Linux 系統的信息,如我想知道系統何時發生系統調用,發生的是什麼系統調用等這些信息,有什麼解決方案呢?linux
下面將會介紹systemtap的安裝、systemtap的工做原理以及幾個簡單的示例。git
個人主機 Linux 發行版是32位 Ubuntu13.04,內核版本 3.8.0-30。因爲 systemtap 運行須要內核的調試信息支撐,默認發行版的內核在配置時這些調試開關沒有打開,因此安裝完systemtap也是沒法去探測內核信息的。 下面我以兩種方式安裝並運行 systemtap:ubuntu
編譯內核以支持systemtap
咱們從新編譯內核讓其支持systemtap,首先你想讓內核中有調試信息,編譯內核時須要加上 -g 標誌;其次,你還須要在配置內核時將 Kprobe 和 debugfs 開關打開。最終效果是,你能在內核 .config 文件中看到下面四個選項是設置的:markdown
CONFIG_DEBUG_INFO CONFIG_KPROBES CONFIG_DEBUG_FS CONFIG_RELAY
配置完以後,按照以前你編譯內核的步驟編譯便可。框架
獲取systemtap源碼
今後地址 https://sourceware.org/systemtap/ftp/releases下載已經發布的systemtap的源代碼,截至目前(2013.9.17)最新版本爲systemtap-2.3。下載完以後解壓。 固然你還可使用 git 去克隆最新的版本(2.4),命令以下:函數
git clone git://sources.redhat.com/git/systemtap.git
編譯安裝systemtap
若是你下載的是最新版本的systemtap,那麼你須要新版的 elfutils,能夠從https://fedorahosted.org/releases/e/l/elfutils/ 下載elfutils-0.156 版本。下載以後解壓縮到適合的目錄(我放在~/Document/ 下),不須要安裝,只要配置systemtap時指定其位置便可。 進入以前解壓systemtap的目錄,使用下面命令進行配置:工具
./configure --with-elfutils=~/Document/elfutils-0.156
以這裏方法配置以後,你只須要再運行 make install 即完成systemtap的編譯安裝。若是須要卸載的話,運行 make uninstall。post
因爲發行版的內核默認無內核調試信息,因此咱們還須要一個調試內核鏡像,在http://ddebs.ubuntu.com/pool/main/l/linux/ 找到你的內核版本相對應的內核調試鏡像(版本號包括後面的發佈次數、硬件體系等都必須一致),如針對我上面的內核版本,就能夠用以下命令下載安裝內核調試鏡像:性能
$ wget http://ddebs.ubuntu.com/pool/main/l/linux/linux-image-debug-3.8.0-30-generic_dbgsym_3.8.0-30.43_i386.ddeb $ sudo dpkg -i linux-image-debug-3.8.0-30-generic_dbgsym_3.8.0-30.43_i386.ddeb
通常這種方法下,你只須要使用apt在線安裝systemtap便可:
$sudo apt-get install systemtap
固然方法二僅限於Ubuntu發行版,至於其餘的發行版並不能照搬,網上也有不少相關的資料。
安裝完systemtap以後,咱們須要測試一下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.
建立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 的核心思想是定義一個事件(event),以及給出處理該事件的句柄(Handler)。當一個特定的事件發生時,內核運行該處理句柄,就像快速調用一個子函數同樣,處理完以後恢復到內核原始狀態。這裏有兩個概念:
Systemtap 工做原理是經過將腳本語句翻譯成C語句,編譯成內核模塊。模塊加載以後,將全部探測的事件以鉤子的方式掛到內核上,當任何處理器上的某個事件發生時,相應鉤子上句柄就會被執行。最後,當systemtap會話結束以後,鉤子從內核上取下,移除模塊。整個過程用一個命令 stap
就能夠完成。 上面只是簡單的原理,更多背後的機理參考網上資料和相應的論文。 圖 systemtap 處理流程