1. 程式人生 > >系統技術非業餘研究 » systemtap如何跟蹤libc.so

系統技術非業餘研究 » systemtap如何跟蹤libc.so

下午和周忱同學折騰複雜程式的記憶體洩漏問題,用了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("
[email protected]
/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("[email protected]/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("[email protected]/home/chuba/t.c:3")
process("/home/chuba/a.out").function("[email protected]/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  }

哈哈,
祝大家玩得開心。

Post Footer automatically generated by wp-posturl plugin for wordpress.