0

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.

Eric Gumba
  • 435
  • 3
  • 16

1 Answers1

0

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)));
}
Eric Gumba
  • 435
  • 3
  • 16