This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[SCRIPT] LKST compatible events script
- From: Masami Hiramatsu <hiramatu at sdl dot hitachi dot co dot jp>
- To: systemtap at sources dot redhat dot com
- Cc: Yumiko Sugita <sugita at sdl dot hitachi dot co dot jp>, Satoshi Oshima <soshima at redhat dot com>, Hideo Aoki <haoki at redhat dot com>
- Date: Thu, 15 Dec 2005 17:32:12 +0900
- Subject: [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 *)(¤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