I modified the kernel introducing a new socket option, as well as a new field in the sock struct. As of now, this works:
probe kernel.statement("sock_setsockopt@sock.c:730")
{
printf("%ul\n", $sk->sk_foo)
}
But as soon as I use regex:
probe kernel.statement("sock_setsockopt@sock.c:*")
{
printf("%ul\n", $sk->sk_foo)
}
I end up getting this error:
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]
The issue with the first example is that in the future, the linux source code might change, and so the systemtap script may no longer work.
The solution is to actually use function.return statement and use embedded C, to retrieve the values.
%{
#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)));
}