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 *)(¤t->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 |
> 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 |
Free forum by Nabble | Edit this page |