安装 systemtap
yum -y install systemtap
编译开关的设置
用户态程序的编译
并不是每个函数都可以探测的。
只有使用了 -g
的调试开关。才可以支持探测。
而且 -O
的优化开关,也会令到探测点减少。
所以最好在编译的时候使用 -O0 -g3
,关闭优化,还有使用高一点的调试级别。
内核的编译
要想编译一个支持Systemtap的内核,必须配置这些内核选项:
Kernel hacking --->
[*] Kernel debugging
[*] Compile the kernel with debug info
Instrumentation Support --->
[*] Kprobes (EXPERIMENTAL)
General setup --->
[*] Kernel->user space relay support (formerly relayfs)
可以用以下符号grep生成的配置文件.config来确认这些配置是否成功:
如果成功,它们应当都为 Y
.
# file: .config
CONFIG_DEBUG_INFO
CONFIG_KPROBES
CONFIG_RELAY
查询函数探测点
使用 stap 的 -l
, -L
可以打印出支持的 探测点。
-g
:专家模式。可以打印更多的探测点。
-l
:只打印出 函数探测点 的函数函数名称,路径,和行号。
输出格式如下
function("<function_name>@<source_file_path>:<line_number>")
。
-L
:在
-l
的基础上,增加探测的变量列表。
输出格式如下
function("<function_name>@<source_file_path>:<line_number>") <function_variable_list>
。
使用方法:
# 查询内核的系统调用
stap -gL 'syscall.*'
# 查询内核的函数探测点
stap -gL 'kernel.function("<function_name>")'
stap -gL 'kernel.function("<function_name>").call' # 函数入口
stap -gL 'kernel.function("<function_name>").return' # 函数出口
# 查询内核模块
stap -gL 'module("<module_name>").function("<function_name>")'
# 查询可执行文件的函数探测点
stap -L 'process("<executable_file_path>").function("<function_name>")'
stap -L 'process("<executable_file_path>").function("<function_name>").call' # 函数入口
stap -L 'process("<executable_file_path>").function("<function_name>").return' # 函数出口
# 查询动态链接库的函数探测点
stap -L 'process("<shared_library_file_path>").function("<function_name>")'
stap -L 'process("<shared_library_file_path>").function("<function_name>").call' # 函数入口
stap -L 'process("<shared_library_file_path>").function("<function_name>").return' # 函数出口
# 查询语句探测点
stap -L 'process("<shared_library_file_path>").statement("<function_name>:@<source_file_path>:*")'
<executable_file_path>
:可执行文件的路径
<shared_library_file_path>
:动态链接库的路径
注意:一定要是ldconfig -p
所登记的路径。
<function_name>
:函数名称。可以使用通配字符匹配。如果要显示所有函数,可以使用 “*”。
例子:
## 查询系统调用
stap -gL 'syscall.*' | grep sendmsg
> syscall.compat_sys_sendmsg name:string s:long msg_uaddr:long flags:long flags_str:string argstr:string $fd:int $msg:struct compat_msghdr* $flags:unsigned int
> syscall.sendmsg name:string s:long msg_uaddr:long flags:long flags_str:string argstr:string $fd:long int $msg:long int $flags:long int
stap -gL 'syscall.sendmsg.return'
> syscall.sendmsg.return name:string retstr:string $return:long int $fd:long int $msg:lo