核心探測工具systemtap簡介

發表於2016-11-12

systemtap是核心開發者必須要掌握的一個工具,本文我將簡單介紹一下此工具,後續將會有系列文章介紹systemtap的用法。

什麼是systemtap

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

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

下面將會介紹systemtap的安裝、systemtap的工作原理以及幾個簡單的示例。

systemtap 的安裝

我的主機 Linux 發行版是32位 Ubuntu13.04,核心版本 3.8.0-30。由於 systemtap 執行需要核心的除錯資訊支撐,預設發行版的核心在配置時這些除錯開關沒有開啟,所以安裝完systemtap也是無法去探測核心資訊的。 下面我以兩種方式安裝並執行 systemtap:

方法一

  1. 編譯核心以支援systemtap
    我們重新編譯核心讓其支援systemtap,首先你想讓核心中有除錯資訊,編譯核心時需要加上 -g 標誌;其次,你還需要在配置核心時將 Kprobe 和 debugfs 開關開啟。最終效果是,你能在核心 .config 檔案中看到下面四個選項是設定的:

    配置完之後,按照之前你編譯核心的步驟編譯即可。
  2. 獲取systemtap原始碼
    從此地址 https://sourceware.org/systemtap/ftp/releases下載已經發布的systemtap的原始碼,截至目前(2013.9.17)最新版本為systemtap-2.3。下載完之後解壓。 當然你還可以使用 git 去克隆最新的版本(2.4),命令如下:
  3. 編譯安裝systemtap
    如果你下載的是最新版本的systemtap,那麼你需要新版的 elfutils,可以從https://fedorahosted.org/releases/e/l/elfutils/ 下載elfutils-0.156 版本。下載之後解壓縮到適合的目錄(我放在~/Document/ 下),不需要安裝,只要配置systemtap時指定其位置即可。 進入之前解壓systemtap的目錄,使用下面命令進行配置:

    以這裡方法配置之後,你只需要再執行 make install 即完成systemtap的編譯安裝。如果需要解除安裝的話,執行 make uninstall

方法二

由於發行版的核心預設無核心除錯資訊,所以我們還需要一個除錯核心映象,在http://ddebs.ubuntu.com/pool/main/l/linux/ 找到你的核心版本相對應的核心除錯映象(版本號包括後面的釋出次數、硬體體系等都必須一致),如針對我上面的核心版本,就可以用如下命令下載安裝核心除錯映象:

一般這種方法下,你只需要使用apt線上安裝systemtap即可:

當然方法二僅限於Ubuntu發行版,至於其他的發行版並不能照搬,網上也有很多相關的資料。

systemtap 測試示例

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

示例一:列印hello systemtap

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

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

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

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

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

systemtap 工作原理

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

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

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

更多參考

相關文章