This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[SCRIPT] LKST compatible events script


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: hiramatu@sdl.hitachi.co.jp




// lkst-compatibility tapset
// Copyright (C) 2005 Hitachi, Ltd., Systems Development Laboratory
// Written by Masami Hiramatsu <hiramatu@sdl.hitachi.co.jp>
//
// 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]