1、查看代码执行路径
在分析代码的时候,能清晰地观察代码执行路径对Debug效率很有帮助,比如,最近在分析内核tcp回复ack的代码执行路径的时候就用到这个技巧,看看下面是tcp回复ack的代码:
我想看看代码执行到if分支里面还是else分支里面,一种办法是分析if的条件是否为真,简单点的条件还好,就上面这段代码要分析if里面的条件肯定很费劲吧,另一种办法就是这里要讲的技巧,就是用systemtap的函数pp(),这个函数能得到当前的探测点,我们只要设置一个*的statement探测点然后把pp()结果打印出来就可以了,代码如下:
root@jusse ~/systemtap# cat tcp_ack_snd_check.stp
probe begin
{
printf("begin\n");
}
probe kernel.statement("__tcp_ack_snd_check@/build/buildd/linux-lts-trusty-3.13.0/net/ipv4/tcp_input.c:*")
{
printf("%s\n", pp());
}
运行之后结果如下:
root@jusse ~/systemtap# stap tcp_ack_snd_check.stp
begin
kernel.statement("__tcp_ack_snd_check@/build/buildd/linux-lts-trusty-3.13.0/net/ipv4/tcp_input.c:4793")
kernel.statement("__tcp_ack_snd_check@/build/buildd/linux-lts-trusty-3.13.0/net/ipv4/tcp_input.c:4797")
kernel.statement("__tcp_ack_snd_check@/build/buildd/linux-lts-trusty-3.13.0/net/ipv4/tcp_input.c:4807")
kernel.statement("__tcp_ack_snd_check@/build/buildd/linux-lts-trusty-3.13.0/net/ipv4/tcp_input.c:4812")
kernel.statement("__tcp_ack_snd_check@/build/buildd/linux-lts-trusty-3.13.0/net/ipv4/tcp_input.c:4793")
kernel.statement("__tcp_ack_snd_check@/build/buildd/linux-lts-trusty-3.13.0/net/ipv4/tcp_input.c:4797")
kernel.statement("__tcp_ack_snd_check@/build/buildd/linux-lts-trusty-3.13.0/net/ipv4/tcp_input.c:4803")
kernel.statement("__tcp_ack_snd_check@/build/buildd/linux-lts-trusty-3.13.0/net/ipv4/tcp_input.c:4805")
kernel.statement("__tcp_ack_snd_check@/build/buildd/linux-lts-trusty-3.13.0/net/ipv4/tcp_input.c:4810")
kernel.statement("__tcp_ack_snd_check@/build/buildd/linux-lts-trusty-3.13.0/net/ipv4/tcp_input.c:4793")
kernel.statement("__tcp_ack_snd_check@/build/buildd/linux-lts-trusty-3.13.0/net/ipv4/tcp_input.c:4797")
kernel.statement("__tcp_ack_snd_check@/build/buildd/linux-lts-trusty-3.13.0/net/ipv4/tcp_input.c:4803")
kernel.statement("__tcp_ack_snd_check@/build/buildd/linux-lts-trusty-3.13.0/net/ipv4/tcp_input.c:4810")
看看上面的结果每行最后都把行号打印出来了,再对照一下代码就可以清晰看到代码的执行路径,很爽吧。。。
2、调试内核模块
这小节就不细讲了,最后的参考网址这篇博客写得很详细,这里只copy两个关键点过来记录一下:
要调试自己的内核模块,要注意的有两个关键点:
1)、使用SystemTap调试内核模块,探测点的编写格式示例为:
module("ext3").function("ext3_*")
2)、需要将自己的模块cp到/lib/modules/`uname -r`/extra目录中,否则找不到符号,如果/lib/modules/`uname -r`/目录下没有extra这个目录,自己mkdir一下就可以。
module("ext3").function("ext3_*")
2)、需要将自己的模块cp到/lib/modules/`uname -r`/extra目录中,否则找不到符号,如果/lib/modules/`uname -r`/目录下没有extra这个目录,自己mkdir一下就可以。
参考: