【63】systemtap--滿足程序猿一切幻想的調試神器

http://sourceware.org/systemtap/

https://sourceware.org/systemtap/wiki

https://sourceware.org/systemtap/documentation.html

https://www.cnblogs.com/hazir/p/systemtap_introduction.html  (推薦)

https://vcpu.me/systemtap-skills/

http://www.redbooks.ibm.com/abstracts/redp4469.html

https://segmentfault.com/a/1190000010774974

https://www.cnblogs.com/hazir/p/systemtap_introduction.html

 

1、安裝

Ubuntu

sudo apt-get install systemtap(不建議這麼玩,Ubuntu自帶的經常有問題)

centos

yum install systemtap systemtap-runtime

也可以通過源碼進行安裝,下載地址:https://sourceware.org/systemtap/ftp/releases/ 。解壓然後進入根目錄,執行如下命令:

tar -zxvf systemtap-4.1.tar.gz 

cd systemtap-4.1/

./configure --prefix=/目錄(期望安裝的目錄)

make

sudo make install

執行配置是可能遇到各種庫找不到,缺啥補啥,常見的庫是下面這些:

sudo apt-get install elfutils

sudo apt-get install libncurses5-dev

sudo apt-get install flex

sudo apt-get install bison

sudo apt-get install gettext

sudo apt-get install libdw-dev

sudo apt-get install g++

2、安裝調試需要debug

首先由於Systemtap運行時需要內核的調試信息支撐,默認發行版的內核在配置時,這些調試開關是關閉的,所以爲了Systemtap能夠正常運行,我們首先要使內核開啓運行調試信息功能。主要有兩種方法:

方法一:下載並安裝debuginfo安裝包

由於發行版的內核默認無內核調試信息,所以我們還需要一個調試內核鏡像,在http://ddebs.ubuntu.com/pool/main/l/linux/ 找到你的內核版本相對應的內核調試鏡像(版本號包括後面的發佈次數、硬件體系等都必須一致),

假設我的內核版本2.6.32-24,i386結構,那麼我需要下載

linux-image-2.6.32-24-generic-dbgsym_2.6.32-24.42_i386.ddeb下載後安裝

dpkg -i linux-image-2.6.32-24-generic-dbgsym_2.6.32-24.42_i386.ddeb

方法二:重新編譯內核

參考:https://blog.csdn.net/linjiasen/article/details/89850357

1.git下載最新的內核源碼
         git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git

                    或者更快的: git clone https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux.git
2 配置kernel
                make memuconfig打開

 General Setup  -- ->

    [*] Kernel->user space relay support (formerly relayfs)

    [*] Kprobes

kernel hacking  -- ->

    [*]Kernel debugging

    [*]Compile the kernel with debug info                    

    [*]Debug Filesystem

然後查看.config下面debug信息是否打開

          CONFIG_DEBUG_INFO
          CONFIG_KPROBES
          CONFIG_RELAY
          CONFIG_DEBUG_FS
          CONFIG_MODULES
          CONFIG_MODULE_UNLOAD
          CONFIG_UPROBES 或者CONFIG_UTRACE

3、測試是否安裝成功

如果pass1-5都沒有錯誤,說明systemtap安裝成功了。

stap -ve 'probe kernel.function("_do_fork") { print("hello world\n") exit() }'

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

stap -ve 'probe begin { log("hello Systemtap!") exit() }'
Pass 1: parsed user script and 476 library scripts using 116624virt/86344res/5540shr/81212data kb, in 280usr/40sys/331real ms.
Pass 2: analyzed script: 1 probe, 2 functions, 0 embeds, 0 globals using 118208virt/88052res/5676shr/82796data kb, in 10usr/0sys/9real ms.
Pass 3: using cached /root/.systemtap/cache/d0/stap_d06faf54f2557de2112cfd40af92ad47_1150.c
Pass 4: using cached /root/.systemtap/cache/d0/stap_d06faf54f2557de2112cfd40af92ad47_1150.ko
Pass 5: starting run.
WARNING: module version mismatch (#1 SMP Tue May 12 20:00:21 CST 2020 vs #1 SMP Tue May 12 16:41:02 CST 2020), release 5.3.0-rc7
hello Systemtap!
Pass 5: run completed in 0usr/10sys/455real ms.

上面打印的pass1-5就是對應SystemTap的處理流程有5個步驟:解析script文件(parse)、細化(elaborate)、script文件翻譯成C語言代碼(translate)、編譯C語言代碼(生成內核模塊)(build)、加載內核模塊(run)。

systemtap 的核心思想是定義一個事件(event),以及給出處理該事件的句柄(Handler)。當一個特定的事件發生時內核運行該處理句柄,就像快速調用一個子函數一樣,處理完之後恢復到內核原始狀態。這裏有兩個概念:

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

evnet有很多種:進入和退出一個function,timer爆發,systemtap的開始和停止。

handler:腳本語言,當event發生時工作。

同步事件包括:

syscall.system_call

vfs.file_operation

kernel.function("function")

kernel.trace("tracepoint")

module("module").function("function")

異步事件包括:

begin

end

timer events

printf

Systemtap 工作原理是通過:將腳本語句翻譯成C語句(Pass1 -3:parse-translate),編譯成內核模塊(Pass4:compile)。模塊加載之後,將所有探測的事件以鉤子的方式掛到內核上(load),當任何處理器上的某個事件發生時相應鉤子上句柄就會被執行(run)。最後,當systemtap會話結束之後,鉤子從內核上取下,移除模塊。整個過程用一個命令 stap 就可以完成。

4、使用

(1) stap

通常直接使用stap執行用SystemTap語法編寫的腳本即可。

stap - systemtap script translator/driver

stap test.stp // .stp後綴的文件是用SystemTap語法編寫的腳本


probe begin
{
        print ("hello world\n")
        exit ()
}

probe end
{
        print ("Bye\n")
}

上面腳本保存成hello_world.stp,然後stap -v hello_world.stp執行,可以看到執行兩條打印。這裏begin和end就是event。

stap -v hello_world.stp 
Pass 1: parsed user script and 476 library scripts using 116628virt/86416res/5608shr/81216data kb, in 260usr/20sys/280real ms.
Pass 2: analyzed script: 2 probes, 1 function, 0 embeds, 0 globals using 118212virt/88124res/5744shr/82800data kb, in 0usr/0sys/9real ms.
Pass 3: translated to C into "/tmp/stapcP149F/stap_95a8df27bac22dee8931f3f1827c6aeb_1046_src.c" using 118212virt/88124res/5744shr/82800data kb, in 0usr/0sys/0real ms.
Pass 4: compiled C into "stap_95a8df27bac22dee8931f3f1827c6aeb_1046.ko" in 2020usr/580sys/2963real ms.
Pass 5: starting run.
WARNING: module version mismatch (#1 SMP Tue May 12 20:00:21 CST 2020 vs #1 SMP Tue May 12 16:41:02 CST 2020), release 5.3.0-rc7
hello world
Bye
Pass 5: run completed in 0usr/30sys/539real ms.

 

(2) staprun

如果我們的輸入不是.stp腳本,而是一個用stap生成的模塊,那麼就用staprun來執行。

staprun - systemtap runtime

staprun [OPTIONS] MODULE [MODULE-OPTIONS]

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章