IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

systemtap函数调用栈信息不齐的原因和解决方法

Erlang非业余研究 2011-03-27 23:41:50 累计浏览 3,227 次
本机暂存
    有时候在看系统代码的时候,我们很难从源码中看出我们感兴趣的函数是如何被调用的,因为调用路径有可能太多。用户空间的程序gdb设断点是个好的方法,内核的就麻烦了。这时候systemtap可以帮忙, 比如:
$uname -r
2.6.18-164.el5

$stap -V
SystemTap translator/driver (version 1.5/0.137 non-git sources)
Copyright (C) 2005-2011 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 NLS

$sudo stap -e \'probe vfs.add_to_page_cache {print_backtrace();println("")}\'
 0xffffffff8000c633 : add_to_page_cache+0x0/0xc1 [kernel]
 0xffffffff800c4565 : add_to_page_cache_lru+0xe/0x22 [kernel]
 0xffffffff80025a10 : find_or_create_page+0x4b/0x72 [kernel]
 0xffffffff80019b72 : __getblk+0x105/0x236 [kernel]
 0xffffffff8803826a
 0xffff811838293600 (inexact)
...

    但是有时候我们并没能得到全部的符号信息, 比如# 0xffffffff8803826a 这行是谁没打印出来吧。 原因是我们的模块可能被未知的模块所调用,这些模块的符号信息没有自动加载,所以systemtap当然就不知道谁是谁了!

    解决方法 man stap 文档写的很清楚:

     -d MODULE

     Add symbol/unwind information for the given module into the kernel object module. This may enable symbolic tracebacks from those mod-

     ules/programs, even if they do not have an explicit probe placed into them.

     -ldd Add symbol/unwind information for all shared libraries suspected by ldd to be necessary for user-space binaries being probe or listed

     with the -d option. Caution: this can make the probe modules considerably larger.

     -all-modules

     Equivalent to specifying “-dkernel” and a “-d” for each kernel module that is currently loaded. Caution: this can make the probe modules

     considerably larger.

$sudo stap --all-modules -e \'probe vfs.add_to_page_cache {print_backtrace();println("")}\'
 0xffffffff8000c633 : add_to_page_cache+0x0/0xc1 [kernel]
 0xffffffff800c4565 : add_to_page_cache_lru+0xe/0x22 [kernel]
 0xffffffff80025a10 : find_or_create_page+0x4b/0x72 [kernel]
 0xffffffff80019b72 : __getblk+0x105/0x236 [kernel]
 0xffffffff8803826a : journal_get_descriptor_buffer+0x30/0x0 [jbd]
 0xffff81183f50c000 (inexact)

    0xffffffff8803826a 这行我们知道是谁了把, jbd. 知道了这个模块我们就可以这样:

$sudo stap -d jbd -e \'probe vfs.add_to_page_cache {print_backtrace();println("")}\'
 0xffffffff8000c633 : add_to_page_cache+0x0/0xc1 [kernel]
 0xffffffff800c4565 : add_to_page_cache_lru+0xe/0x22 [kernel]
 0xffffffff80025a10 : find_or_create_page+0x4b/0x72 [kernel]
 0xffffffff80019b72 : __getblk+0x105/0x236 [kernel]
 0xffffffff8803826a : journal_get_descriptor_buffer+0x30/0x0 [jbd]
 0xffff81183f50c000 (inexact)
...

    二个一样的的运行效果,只是生成的模块大小不一样,我们来看下:

$sudo stap -d jbd -m demo -p4 -e \'probe vfs.add_to_page_cache {print_backtrace();println("")}\'
demo.ko
$ll demo.ko
-rw-r--r-- 1 root root 2943293 Mar 26 22:14 demo.ko

$sudo stap --all-modules -m demo -p4 -e \'probe vfs.add_to_page_cache {print_backtrace();println("")}\'
demo.ko
$ll demo.ko
-rw-r--r-- 1 root root 3890409 Mar 26 22:15 demo.ko

     -all-modules的生成要大不少,不过很适合我们这样的懒人!

    用户空间的程序用-ldd来搞定!

同分类推荐文章

  1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. Linux如何统计进程的CPU利用率 (累计阅读 16,308)
  2. 我的 RHCA 之路 (累计阅读 14,013)
  3. Linux内存点滴 用户进程内存空间 (累计阅读 13,230)
  4. 给程序员新手的一些建议 (累计阅读 13,089)
  5. Linux 性能监控、测试、优化工具 (累计阅读 13,011)
  6. 关于linux内存free的一些事情 (累计阅读 12,867)
  7. ps - 按进程消耗内存多少排序 (累计阅读 12,688)
  8. Google怎么用linux (累计阅读 12,581)
  9. Linux Used内存到底哪里去了? (累计阅读 11,868)
  10. find命令的一点注意事项 (累计阅读 11,866)