Systemtap: learning notes

Before using stap, the kernel-debuginfo-$(uname -r), kernel-debuginfo-common-$(uname -m)-$(uname -r) and kernel-devel-$(uname -r) should be installed. (CentOS)

stap-prep is a shortcut, but in the end, the above 3 packages should present.

verbose manpage over stap: man stapprobes

Another doc of stap will be included as file  of this blog.

Normal usage of stap file: (its format is loose)

#!/bin/stap
global cntread, cntwrite, cntother

probe kernel.function("vfs_read"), kernel.function("vfs_write"), kernel.function(@1)
{
        if (probefunc() == "vfs_read")
                cntread++;
        else if (probefunc() == "vfs_write")
                cntwrite++;
        else
                cntother++;
}

probe timer.s(5){
        exit();
}

probe end {
        printf("Read: %d\nWrite: %d\nOther: %d\n", cntread, cntwrite, cntother);
}

Run by: stap stap.stp -v/-vvv -- vfs_open (Note: vfs_open as first argument passed to stp script which replaces @1)

More usages can be viewed through installing systemtap-testsuite, normally sits at /usr/share/systemtap/testsuite/

And many predefined kernel probe functions can be found at /usr/share/systemtap/tapset/, functions/probes defined in these files can be used directly in user defined stp files. Learning stap first need to check these functions.

# These functions utilizes the available kernel probes listed in /sys/kernel/debug/tracing/available_events.

 

---Adding more info about writing self using stp files----

Quote from here:

#!/bin/stap -g   // using embedded C code should be under guru-mode
%{
#include <linux/in.h>
#include <linux/ip.h>
%} /* <-- top level */

function read_iphdr:long(skb:long) %{ /* pure */
  struct iphdr *iph = ip_hdr((struct sk_buff *)STAP_ARG_skb);
  STAP_RETVALUE = (long)iph;
%} /* <-- function body */

/* Determines whether an IP packet is TCP, based on the iphdr: */
function is_tcp_packet:long(iphdr) {
  protocol = @cast(iphdr, "iphdr")->protocol
  return (protocol == %{ IPPROTO_TCP %}) /* <-- expression */
}

probe begin {
  printf("SystemTap start!\n");
}

probe kernel.function("ip_local_deliver") {
  iph = read_iphdr(pointer_arg(1));
  printf("tcp packet ? %s\n", is_tcp_packet(iph) ? "yes" : "no");
}

In the above example, we probe the kernel function ip_local_deliver which is on the way of resolving packet in layer 3(after accepting the packet as local destined packet). The function prototype is: 

int ip_local_deliver(struct sk_buff *skb)

where skb is passed in as one packet (GRO-ed).

So when we probe this funcction, we refer to this skb by function pointer_arg(1). The definition of function pointer_arg is located at 

./tapset/x86_64/registers.stp:240:

..... and this is to push probe while entering function(prelogue), if need to put probe while leaving function(epilogue), use kernel.function("..").return

 ------------

And stap has several different code pattern:

  1. PRE-PROCESSING: %(condition %? then [%: else ] %)
  2. embedded C code: %{ c codes %}
  3. normal codes: { stp codes }
  4. embedded C code as r-value: a=1+%{IPPROTO_TCP%} //Should #include <linux/in.h> first

 

posted on 2018-07-15 18:48  三叁  阅读(267)  评论(0编辑  收藏  举报

导航