相關技術:utrace, probe, ftrace, dtrace, pstrace
重點是需要內核的匹配
1.首先先查看你的內核版本
uname -a
2.6.18-194.el5
如果你的內核版本比較老的話,你需要去查找你需要的kernel-devel 的版本.
如果你想用yum去安裝,你可以用 yum install kernel-devel
注意:在最新的yum里面安裝的總是最新的kernel-devel的版本,kernel-devel 需要匹配內核版本
比如: CentOS release 5.5 (Final)用的是內核版本 2.6.18-194.el5
先下載 和內核版本一樣的對應的
然后安裝
rpm-ivh kernel-devel-2.6.18-194.el5-i686.rpm
安裝好kernel-devel會有內核的目錄在
/usr/src/kernels/2.6.18-194.el5-i686/
2.安裝systemtap
yum install systemtap (stap -V 1.3/0.137 請安裝elfutils-devel 才能提示你需要安裝哪個版本的debuginfo)
3. 安裝debuginfo 去
尋找和你內核完全匹配
(例如本機uname -r 2.6.18-194.el5 只能選
kernel-debuginfo-2.6.18-194.el5.i686.rpm
kernel-debuginfo-common-2.6.18-194.el5.i686.rpm
)
kernel-debuginfo-common-xxxxx
kernel-debuginfo-xxxx
如果你找不到對應的內核版本的rpm,你可以去google 去尋找,可以使用redhat的debuginfo rpm 包
redhat內核參考下載
安裝rpm -ivh kernel-debuginfo*.rpm
如何測試:
stap -ve 'probe begin { log("hello world") exit() }'
備注
官方推薦的安裝命令
2 yum install systemtap kernel-devel yum-utils
debuginfo-install kernel 由於我的Centos yum repository上沒有kernel-debuginfo包,於是得手工添加有這個包的repository。當然也可以把這個包及依賴包rpm文件下載到本地安裝。
在/etc/yum.repos.d新建一個文件,我把他命令為debuginfo
1
然后在debuginfo中加入
2
3
4
5
6 [debuginfo]
name=CentOS-$releasever - debuginfo
baseurl=http://debuginfo.centos.org/5/
gpgcheck=0
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5 然后在執行官方推薦的安裝命令的命令就可以了。整個過程要下載300多M文件,因此需要很長的時間。
官方wiki:
http://sourceware.org/systemtap/wiki/SystemTapOnCentOS
下午和周忱同學折騰復雜程序的內存泄漏問題,用了valgrind, gogle perftools等工具都不大好用,很容易把應用程序搞死,於是打算用systemtap來在libc.so層面了解內存的使用情況。主要思路就是看 malloc/realloc和free的調用次數的平衡。
首先准備下環境,系統是標准的RHEL 5u4:
$ uname -r 2.6.18-164.el5 $ stap -V SystemTap translator/driver (version 1.3/0.137 non-git sources) Copyright (C) 2005-2010 Red Hat, Inc. and others This is free software; see the source for copying conditions. enabled features: LIBRPM LIBSQLITE3 NSS BOOST_SHARED_PTR TR1_UNORDERED_MAP $stap -L 'kernel.function("printk")' kernel.function("printk@kernel/printk.c:533") $fmt:char const* $args:va_list $ stap -L 'process("/lib64/libc.so.6").function("malloc")' Missing separate debuginfos, use: debuginfo-install glibc-2.5-42.x86_64
內核的符號是OK的,glibc沒有安裝符號。系統提示用 debuginfo-install glibc-2.5-42.x86_64 命令安裝符號信息,但是RHEL 5不交錢不能用這個服務的,只能自己下載包安裝。
$ wget -c ftp.redhat.com/pub/redhat/linux/enterprise/5Server/en/os/x86_64/Debuginfo/glibc-debuginfo-2.5-42.x86_64.rpm $ sudo rpm -i glibc-debuginfo-2.5-42.x86_64.rpm $ stap -L 'process("/lib64/libc.so.6").function("malloc")' process("/lib64/libc-2.5.so").function("__libc_malloc@/usr/src/debug/glibc-2.5-20061008T1257/malloc/malloc.c:3560") $bytes:size_t
這次有了glibc的符號了,可以方便的跟蹤libc.so中malloc的使用情況。
接着我們來簡單的寫個c程序調用malloc, 同時寫個stap腳本來跟蹤malloc的調用堆棧:
$ cat t.c #include <stdlib.h> void fun() { malloc(1000); } int main(int argc, char *argv[]) { fun(); return 0; } $cat m.stp probe process("/lib64/libc.so.6").function("malloc") { if (target()== pid()) { print_ubacktrace(); exit(); } } probe begin { println("~"); } $ gcc -g t.c $ stap -L 'process("./a.out").function("*")' process("/home/chuba/a.out").function("fun@/home/chuba/t.c:3") process("/home/chuba/a.out").function("main@/home/chuba/t.c:7") $argc:int $argv:char**
現在程序准備好了,那么我們來執行下看內存泄漏在那里:
$sudo stap m.stp -c ./a.out ~ 0x33d5e74b96 : malloc+0x16/0x230 [libc-2.5.so] 0x4004a6 [a.out+0x4a6/0x1000]
我們看到在a.out的0x4004a6的地方地方調用了malloc, 但是具體在程序里面是哪行呢? 用add2line就很容易找出來:
$ addr2line -e ./a.out 0x4004a6 /home/chuba/t.c:5 $ nl t.c 1 #include <stdlib.h> 2 void fun() { 3 malloc(1000); 4 } 5 int main(int argc, char *argv[]) { 6 fun(); 7 return 0; 8 }
Linux 下的一個全新的性能測量和調式診斷工具 Systemtap 系列
systemtap manual
redhat systemtap introduce(pdf) 文庫鏈接
ftp://ftp.redhat.com/pub/redhat/linux/enterprise/5Server/en/os/i386/Debuginfo