如何在不指定行号的情况下在Systemtap中检索和打印本地结构字段的值



我修改了内核,引入了一个新的套接字选项,以及sock结构中的一个新字段。截至目前,这项工作:

probe kernel.statement("sock_setsockopt@sock.c:730")
{
printf("%uln", $sk->sk_foo)
}

但一旦我使用regex:

probe kernel.statement("sock_setsockopt@sock.c:*")
{
printf("%uln", $sk->sk_foo)
}

我最终得到了这个错误:

semantic error: not accessible at this address (pc: 0xffffffff81736f75) [man error::dwarf]: identifier '$sk' at sock_analysis.stp:22:9
dieoffset: 0x9229d6a from /usr/lib/debug/lib/modules/5.4.114+/vmlinux
function: sock_setsockopt at net/core/sock.c:724:1
alternative locations: [0xffffffff81736f8d,0xffffffff8173706b], [0xffffffff8173706c,0xffffffff81737c2c]

第一个例子的问题是,在未来,linux源代码可能会更改,因此systemtap脚本可能不再工作。

解决方案是实际使用function.return语句并使用嵌入式C来检索值。

%{
#include <net/sock.h>
#include <linux/net.h>
%}
function get_sk_value:long (val:long) %{
struct socket *x = (struct socket *)STAP_ARG_val;
STAP_RETURN(x->sk->sk_foo);
%}

probe kernel.function("sock_setsockopt").return
{
SO_NEW_SOCK_OPTION = 69
if (@entry($optname) == SO_NEW_SOCK_OPTION)
sprintf("%d", get_sk_val(@entry($sock)));
}