• 内核调试 SystemTap


    相关技术: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 去

    http://debuginfo.centos.org

    寻找和你内核完全匹配

    (例如本机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内核参考下载

    http://rpm.pbone.net/index.php3/stat/4/idpl/13968571/dir/redhat_el_5/com/kernel-debuginfo-common-2.6.18-128.el5.x86_64.rpm.html

    ftp://ftp.pbone.net/mirror/ftp.redhat.com/pub/redhat/linux/enterprise/5Server/en/os/x86_64/Debuginfo/kernel-debuginfo-2.6.18-128.el5.x86_64.rpm

    安装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
    然后在debuginfo中加入
    1

    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


    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("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  }

    参考连接

    erlang 非业余研究

    ibm Linux 自检和 SystemTap

    Linux 下的一个全新的性能测量和调式诊断工具 Systemtap 系列

    systemtap manual

    redhat systemtap introduce(pdf)  文库链接

    ftp://ftp.redhat.com/pub/redhat/linux/enterprise/5Server/en/os/i386/Debuginfo

  • 相关阅读:
    置换加密算法
    堆和优先队列的应用
    定时发送邮件小程序
    Hibernate的缓存
    Spring中使用JDBC
    Spring AOP(创建切面)
    处理不可中断阻塞
    SQL语句实例说明
    spring_声明式事务
    Flex_includeIn属性的作用
  • 原文地址:https://www.cnblogs.com/wangkangluo1/p/2562971.html
Copyright © 2020-2023  润新知