[SCRIPT] LKST compatible events script

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[SCRIPT] LKST compatible events script

Masami Hiramatsu
Hi,

Here is the Linux Kernel State Tracer (LKST) compatible events
stap script. This covers a half of events of LKST, and I will
implement remaining half of events as much as possible. However
I noticed some events of LKST can not be implemented on current
SystemTap. For example, the return probe can not be inserted on
the return of do_execve. Also, the arguments of inline functions
can not be accessed from probes. So, I commented out those events.

This stap script can work efficiently with Binary Transport Interface
(BTI) though this does not require the BTI.
I released full source code package that includes LKST events stap
script, BTI patches and sample scripts on the sourceforge.net.
You can download it from:
http://prdownloads.sourceforge.net/lkst/stptracer-20051215.tar.bz2?download

Best Regards,
--
Masami HIRAMATSU
2nd Research Dept.
Hitachi, Ltd., Systems Development Laboratory
E-mail: [hidden email]





// lkst-compatibility tapset
// Copyright (C) 2005 Hitachi, Ltd., Systems Development Laboratory
// Written by Masami Hiramatsu <[hidden email]>
//
// This file is free software.  You can redistribute it and/or modify
// it under the terms of the GNU General Public License (GPL); either
// version 2, or (at your option) any later version.

#if 0

global ETYPE_IGNORE
global ETYPE_SYNCTIME

global ETYPE_SYSCALL_ENTRY
global ETYPE_SYSCALL_EXIT

global ETYPE_BIO_SUBMIT
global ETYPE_BIO_ENDIO
global ETYPE_ELV_NEXTREQ
global ETYPE_BLK_GETREQ
global ETYPE_BLK_PUTREQ
global ETYPE_BUF_SUBMIT_BH
global ETYPE_BUF_ENDIO_BH

global ETYPE_IPC_SEMOP
global ETYPE_IPC_SEMGET
global ETYPE_IPC_SEMCTL
global ETYPE_IPC_MSGSND
global ETYPE_IPC_MSGRCV
global ETYPE_IPC_MSGGET
global ETYPE_IPC_MSGCTL
global ETYPE_IPC_SHMAT
global ETYPE_IPC_SHMDT
global ETYPE_IPC_SHMGET
global ETYPE_IPC_SHMCTL

global ETYPE_NET_PKTSEND
global ETYPE_NET_PKTSENDI
global ETYPE_NET_PKTRECV
global ETYPE_NET_PKTRECVI

global ETYPE_OOPS_DIE
global ETYPE_OOPS_NMI
global ETYPE_OOPS_PANIC
global ETYPE_PROC_INIT_WQH
global ETYPE_PROC_ADD_WQ
global ETYPE_PROC_REM_WQ
global ETYPE_PROC_KTHREAD
global ETYPE_PROC_SIGHAND
global ETYPE_PROC_SIGSEND
global ETYPE_PROC_EXEC
global ETYPE_PROC_FORK
global ETYPE_PROC_FORKED
global ETYPE_PROC_WAKEUP
global ETYPE_PROC_SWITCH

function VAL:long (v:long) { return v }

%{
#include <linux/kernel.h>
#include <linux/blkdev.h>
#include <linux/cpufreq.h>
#include <linux/buffer_head.h>
%}

function cpu_khz:long () %{
        THIS->__retvalue = cpu_khz;
%}

function get_eip:long() %{
        THIS->__retvalue = (int64_t)CONTEXT->regs->eip;
%}

/* this can be called from only "function" probes */
function get_caller:long () %{
        THIS->__retvalue = (int64_t)(*(long *)CONTEXT->regs->esp);
%}

function get_tsc:long () %{
        rdtscll(THIS->__retvalue);
%}

function get_cpu:long () %{
        THIS->__retvalue = smp_processor_id();
%}

function get_request_queue:long (request:long) %{
         struct request *rq;
         rq = (struct request *)((long)THIS->request);
         THIS->__retvalue = (long)rq->q;
%}

function get_sector:long (request:long) %{
         struct request *rq;
         rq = (struct request *)((long)THIS->request);
         THIS->__retvalue = (int64_t)rq->sector;
%}

function get_nr_sectors:long (request:long) %{
         struct request *rq;
         rq = (struct request *)((long)THIS->request);
         THIS->__retvalue = (int64_t)rq->nr_sectors;
%}

function get_data_dir:long (request:long) %{
         struct request *rq;
         rq = (struct request *)((long)THIS->request);
         THIS->__retvalue = (int64_t)rq->flags & 1;
%}

function get_bh_page:long (bh:long) %{
        struct buffer_head *bh = (struct buffer_head *)(long)THIS->bh;
        THIS->__retvalue = (long)bh->b_page;
%}

function get_task_state:long (task:long) %{
        struct task_struct *tsk = (struct task_struct *)(long)THIS->task;
        if (unlikely(tsk == NULL))
                THIS->__retvalue = (int64_t)0;
        else
                THIS->__retvalue = (int64_t)tsk->state;
%}

function get_comm1:long () %{
        THIS->__retvalue = (*(int64_t *)current->comm);
%}
function get_comm2:long () %{
        THIS->__retvalue = (*(int64_t *)(&current->comm[8]));
%}

probe begin {
#endif
#define VAL(v) v,
        ETYPE_IGNORE = VAL(-1)
        ETYPE_SYNCTIME = VAL(0)
        ETYPE_SYSCALL_ENTRY = VAL(0x030)
        ETYPE_SYSCALL_EXIT = VAL(0x031)
        ETYPE_BIO_SUBMIT = VAL(0x0d2)
        ETYPE_BIO_ENDIO = VAL(0x0d3)
        ETYPE_ELV_NEXTREQ = VAL(0x0d7)
        ETYPE_BLK_GETREQ = VAL(0x0d4)
        ETYPE_BLK_PUTREQ = VAL(0x0d5)
        ETYPE_IPC_SEMOP = VAL(0x070)
        ETYPE_IPC_SEMGET = VAL(0x071)
        ETYPE_IPC_SEMCTL = VAL(0x072)
        ETYPE_IPC_MSGSND = VAL(0x073)
        ETYPE_IPC_MSGRCV = VAL(0x074)
        ETYPE_IPC_MSGGET = VAL(0x075)
        ETYPE_IPC_MSGCTL = VAL(0x076)
        ETYPE_IPC_SHMAT = VAL(0x077)
        ETYPE_IPC_SHMDT = VAL(0x078)
        ETYPE_IPC_SHMGET = VAL(0x079)
        ETYPE_IPC_SHMCTL = VAL(0x07a)
        ETYPE_NET_PKTSEND = VAL(0x060)
        ETYPE_NET_PKTSENDI = VAL(0x061)
        ETYPE_NET_PKTRECV = VAL(0x062)
        ETYPE_NET_PKTRECVI = VAL(0x063)
        ETYPE_OOPS_DIE = VAL(0x0b0)
        ETYPE_OOPS_NMI = VAL(0x0b1)
        ETYPE_OOPS_PANIC = VAL(0x0b2)
        ETYPE_PROC_SWITCH = VAL(0x001)
        ETYPE_PROC_WAKEUP = VAL(0x002)
        ETYPE_PROC_SIGSEND = VAL(0x003)
        ETYPE_PROC_KTHREAD = VAL(0x004)
        ETYPE_PROC_INIT_WQH = VAL(0x005)
        ETYPE_PROC_ADD_WQ = VAL(0x006)
        ETYPE_PROC_REM_WQ = VAL(0x007)
        ETYPE_PROC_FORKED = VAL(0x009)
        ETYPE_PROC_FORK = VAL(0x00a)
        ETYPE_PROC_EXET = VAL(0x00b)
        ETYPE_PROC_EXEC = VAL(0x00c)
        ETYPE_PROC_SIGHAND = VAL(0x00e)
        ETYPE_BUF_SUBMIT_BH = VAL(0x0d0)
        ETYPE_BUF_ENDIO_BH = VAL(0x0d1)
#if 0
      //print ("start tracing");
}

probe end {
      //print ("end tracing");
}

probe kernel.trace.ipc.semop = kernel.function("sys_semop") {
        etype = ETYPE_IPC_SEMOP;
        arg1 = $semid; arg2 = $tsops; arg3 = $nsops; arg4 = 0;
}

probe kernel.trace.ipc.semget = kernel.function("sys_semget") {
        etype = ETYPE_IPC_SEMGET;
        arg1 = $key; arg2 = $nsems; arg3 = $semflg; arg4 = 0;
}

probe kernel.trace.ipc.semctl = kernel.function("sys_semctl") {
        etype = ETYPE_IPC_SEMCTL;
        arg1 = $semid; arg2 = $semnum; arg3 = $cmd; arg4 = $arg->val;
}

probe kernel.trace.ipc.msgsnd = kernel.function("sys_msgsnd") {
        etype = ETYPE_IPC_MSGSND;
        arg1 = $msqid; arg2 = $msgp; arg3 = $msgsz; arg4 = $msgflg;
}

probe kernel.trace.ipc.msgrcv = kernel.function("sys_msgrcv") {
        etype = ETYPE_IPC_MSGRCV;
        arg1 = $msqid; arg2 = $msgp; arg3 = $msgsz; arg4 = $msgflg;
}

probe kernel.trace.ipc.msgget = kernel.function("sys_msgget") {
        etype = ETYPE_IPC_MSGGET;
        arg1 = $key; arg2 = $msgflg; arg3 = 0; arg4 = 0;
}

probe kernel.trace.ipc.msgctl = kernel.function("sys_msgctl") {
        etype = ETYPE_IPC_MSGCTL;
        arg1 = $msqid; arg2 = $cmd; arg3 = $buf; arg4 = 0;
}

probe kernel.trace.ipc.shmat = kernel.function("sys_shmat") {
        etype = ETYPE_IPC_SHMAT;
        arg1 = $shmid; arg2 = $shmaddr; arg3 = $shmflg; arg4 = 0;
}

probe kernel.trace.ipc.shmdt = kernel.function("sys_shmdt") {
        etype = ETYPE_IPC_SHMDT;
        arg1 = $shmaddr; arg2 = 0; arg3 = 0; arg4 = 0;
}

probe kernel.trace.ipc.shmget = kernel.function("sys_shmget") {
        etype = ETYPE_IPC_SHMGET;
        arg1 = $key; arg2 = $size; arg3 = $shmflg; arg4 = 0;
}

probe kernel.trace.ipc.shmctl = kernel.function("sys_shmctl") {
        etype = ETYPE_IPC_SHMCTL;
        arg1 = $shmid; arg2 = $cmd; arg3 = $buf; arg4 = 0;
}

// instead of BIO_MAKE_REQ
probe kernel.trace.bio.submit = kernel.function("submit_bio") {
        etype = ETYPE_BIO_SUBMIT;
        arg1 =  $bio; arg2 =  0; arg3 = $rw; arg4 = 0;
}

probe kernel.trace.bio.endio = kernel.function("bio_endio") {
        etype = ETYPE_BIO_ENDIO;
        arg1 = $bio; arg2 = 0; arg3 = 0; arg4 = $bio->bi_bdev->bd_dev;
}

probe kernel.trace.blk.getreq = kernel.function("get_request") {
        if ($rw == 0) {
                count = $q->rq->count[0];
        } else {
                count = $q->rq->count[1];
        }
        etype = ETYPE_BLK_GETREQ;
        arg1 = $q; arg2 = $rw; arg3 = count; arg4 = 0;
}

probe kernel.trace.blk.putreq = kernel.function("__blk_put_request") {
        rw = get_data_dir($req);
        if (rw == 0) {
                count = $q->rq->count[0];
        } else {
                count = $q->rq->count[1];
        }
        etype = ETYPE_BLK_PUTREQ;
        arg1 = $q; arg2 = rw; arg3 = count; arg4 = req;
}

//LKST_ETYPE_BUFFER_SUBMIT_BH
probe kernel.trace.buf.submit = kernel.function("submit_bh") {
        etype = ETYPE_BUF_SUBMIT_BH;
        arg1 = $bh; arg2 = $bh->b_page;
        arg3 = $rw; arg4 = $bh->b_size;
}

// LKST_ETYPE_BUFFER_ENDIO_BH
probe kernel.trace.buf.endio = kernel.function("end_bio_bh_io_sync") {
        etype = ETYPE_BUF_ENDIO_BH;
        arg1 = $bio->bi_private; arg2 = get_bh_page($bio->bi_private);
        arg3 = $err; arg4 = 0/*$bytes_done;*/
}

probe kernel.trace.elv.nextreq = kernel.function("elv_next_request").return {
        rq = retval();
        if ( rq == 0 ) {
                next;
        } else {
                etype = ETYPE_ELV_NEXTREQ;
                arg1 = get_request_queue(rq); arg2 = rq;
                arg3 = get_sector(rq); arg4 = get_nr_sectors(rq);
        }
}


probe kernel.trace.net.pktsend = kernel.function("dev_queue_xmit") {
        etype = ETYPE_NET_PKTSEND;
        arg1 = $skb; arg2 = 0; arg3 = 0; arg4 = 0;
}

probe kernel.trace.net.pktrecv = kernel.function("netif_rx") {
        etype = ETYPE_NET_PKTRECV;
        arg1 = $skb; arg2 = 0; arg3 = 0; arg4 = 0;
}

probe kernel.trace.net.pktsendi = kernel.function("net_tx_action") {
        etype = ETYPE_NET_PKTSENDI;
        arg1 = $h; arg2 = 0; arg3 = 0; arg4 = 0;
}

probe kernel.trace.net.pktrecvi = kernel.function("net_rx_action") {
        etype = ETYPE_NET_PKTRECVI;
        arg1 = $h; arg2 = 0; arg3 = 0; arg4 = 0;
}

probe kernel.trace.proc.kthread = kernel.function("kernel_thread") {
        etype = ETYPE_PROC_KTHREAD;
        arg1 = $fn; arg2 = $arg; arg3 = $flags; arg4 = 0;
}

probe kernel.trace.proc.sighand = kernel.function("handle_signal") {
        etype = ETYPE_PROC_SIGHAND;
        arg1 = $sig; arg2 = pid(); arg3 = $info; arg4 = 0;
}

probe kernel.trace.proc.sigsend = kernel.function("send_signal") {
        etype = ETYPE_PROC_SIGSEND;
        arg1 = $sig; arg2 = $t; arg3 = $info; arg4 = 0;
}
/*
probe kernel.trace.proc.exec = kernel.function("do_execve").return {
        etype = ETYPE_PROC_EXEC;
        arg1 = pid(); arg2 = get_comm1(); arg3 = get_comm2(); arg4 = retval();
}*/

probe kernel.trace.proc.exit = kernel.function("do_exit") {
        etype = ETYPE_PROC_EXIT;
        arg1 = pid(); arg2 = $code; arg3 = 0; arg4 = 0;
}

probe kernel.trace.proc.fork = kernel.function("do_fork") {
        etype = ETYPE_PROC_FORK;
        arg1 = pid(); arg2 = $clone_flags; arg3 = $stack_start;
        arg4 = $stack_size;
}

probe kernel.trace.proc.forked = kernel.function("do_fork").return {
        etype = ETYPE_PROC_FORKED;
        arg1 = retval(); arg2 = 0; arg3 = 0; arg4 = 0;
}

probe kernel.trace.proc.wakeup = kernel.function("try_to_wake_up") {
        etype = ETYPE_PROC_WAKEUP;
        arg1 = $p; arg2 = $state; arg3 = $sync; arg4 = 0;
}

probe kernel.trace.proc.switch = kernel.function("__switch_to") {
        etype = ETYPE_PROC_SWITCH;
        /*for i386*/
        arg1 = $prev_p; arg2 = $next_p;
        arg3 = get_task_state($prev_p); arg4 = 0;
}

/* currently, in inline-probe, we can not access to local variables
probe kernel.trace.proc.init_wqh = kernel.inline("init_waitqueue_head") {
        etype = ETYPE_PROC_INIT_WQH;
        arg1 = $q; arg2 = get_eip(); arg3 = 0; arg4 = 0;
}

probe kernel.trace.proc.add_wq = kernel.inline("__add_wait_queue") {
        etype = ETYPE_PROC_ADD_WQ;
        arg1 = $head; arg2 = $new->task; arg3 = get_eip(); arg4 = 0;
}

probe kernel.trace.proc.add_wq2 = kernel.inline("__add_wait_queue_tail") {
        etype = ETYPE_PROC_ADD_WQ;
        arg1 = $head; arg2 = $new->task; arg3 = get_eip(); arg4 = 0;
}

probe kernel.trace.proc.rem_wq = kernel.inline("__remove_wait_queue") {
        etype = ETYPE_PROC_REM_WQ;
        arg1 = $head; arg2 = $old->task; arg3 = get_eip(); arg4 = 0;
}
*/

probe kernel.trace.oops.die = kernel.function("die") {
        etype = ETYPE_OOPS_DIE;
        arg1 = $regs->eip; arg2 = $regs->esp; arg3 = 0; arg4 = 0;
}

/* i386 only? */
probe kernel.trace.oops.nmi = kernel.function("die_nmi") {
        etype = ETYPE_OOPS_NMI;
        arg1 = $regs->eip; arg2 = 0; arg3 = 0; arg4 = 0;
}

probe kernel.trace.oops.panic = kernel.function("panic") {
        etype = ETYPE_OOPS_PANIC;
        arg1 = get_caller(); arg2 = 0; arg3 = 0; arg4 = 0;
}

#endif // for c including

Reply | Threaded
Open this post in threaded view
|

Re: [SCRIPT] LKST compatible events script

Li Guanglei
> probe kernel.trace.proc.add_wq = kernel.inline("__add_wait_queue") {
> etype = ETYPE_PROC_ADD_WQ;
> arg1 = $head; arg2 = $new->task; arg3 = get_eip(); arg4 = 0;
> }
>
But it seems that currently systemtap can't support accessing the
parameters of an inline function. it's in bugzilla #1155