MINI SHELL

Server : Apache/2.2.2 (Fedora)
System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686
User : apache ( 48)
PHP Version : 5.2.9
Disable Function : NONE
Directory :  /usr/share/systemtap/tapset/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //usr/share/systemtap/tapset/signal.stp
// Signal tapset
// Copyright (C) 2006 IBM Corp.
// Copyright (C) 2006 Intel Corporation.
//
// This file is part of systemtap, and 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.
//
//   Note : Since there are so many signals sent to processes at any give
//          point, it's better to filter the information according to the
//          requirements.  For example, filter only for a particular signal
//          (if sig==2) or filter only for a particular process
//          (if pid_name==stap).
//


/* probe signal.send
 *
 * Fires when a signal is sent to a process.
 *
 * Context:
 *  The signal's sender.
 *
 * Arguments:
 *  sig - the number of the signal
 *  sig_name - a string representation of the signal
 *  sig_pid - pid of the signal recipient process
 *  pid_name - name of the signal recipient process
 *  si_code - indicates the signal type.
 *  task - a task handle to the signal recipient
 *  sinfo - the address of siginfo struct.
 *  shared - indicates whether this signal is shared by the thread group
 *  send2queue- indicates whether this signal is sent to an existing sigqueue
 *  name - name of the function used to send out this signal
 */
probe signal.send = _signal.send.*
{
    sig=$sig
    sig_name = _signal_name($sig)
    sig_pid = task_pid(task)
    pid_name = task_execname(task)

    if (sinfo == 2)
        si_code ="SIGSTOP or SIGKILL"
    else if (sinfo > 0)
        si_code="SI_KERNEL (SIGFPE, SIGSEGV, SIGTRAP, SIGCHLD, SIGPOLL)"
    else if (sinfo <= 0)
        si_code="SI_USER or SI_TIMER or SI_ASYNCIO"
}

probe _signal.send.part1 = kernel.function("__group_send_sig_info")
{
    name = "__group_send_sig_info"
    task = $p
    sinfo = $info
    shared = 1
    send2queue = 0
}

probe _signal.send.part2 = kernel.function("send_group_sigqueue")
{
    name = "send_group_sigqueue"
    task = $p
    sinfo = $q->info
    shared = 1
    send2queue = 1
}

probe _signal.send.part3 = kernel.function("send_sigqueue")
{
    name = "send_sigqueue"
    task = $p
    sinfo = $q->info
    shared = 0
    send2queue = 1
}

probe _signal.send.part4 = kernel.function("specific_send_sig_info")
{
    name = "specific_send_sig_info"
    task = $t
    sinfo = $info
    shared = 0
    send2queue = 0
}

/* probe signal.send.return
 */
probe signal.send.return = _signal.send.*.return
{
    retstr = returnstr(1)
}

/* 
 * Return values for "__group_send_sig_info" and "specific_send_sig_info"
 *
 * - return 0 if  the signal is sucessfully sent to a process, 
 *   which means the following:
 *     <1> the signal is ignored by receiving process
 *     <2> this is a non-RT signal and we already have one queued
 *     <3> the signal is successfully added into the sigqueue of 
 *        receiving process
 *
 * - return -EAGAIN if the sigqueue is overflow the signal was RT
 *   and sent by user using something other than kill()
 *
 */
probe _signal.send.part1.return = kernel.function("__group_send_sig_info").return
{
    name = "__group_send_sig_info"
    shared = 1
    send2queue = 0
}

probe _signal.send.part4.return = kernel.function("specific_send_sig_info").return
{
    name = "specific_send_sig_info"
    shared = 0
    send2queue = 0
}

/*
 * - return 0 if the signal is either sucessfully added into the 
 *   sigqueue of receiving process or a SI_TIMER entry is already
 *   queued so just increment the overrun count
 *
 * - return 1 if this signal is ignored by receiving process
 *
 */
probe _signal.send.part2.return = kernel.function("send_group_sigqueue").return
{
    name = "send_group_sigqueue"
    shared = 1
    send2queue = 1
}

/*
 * - return 0 if the signal is either sucessfully added into the 
 *   sigqueue of receiving process or a SI_TIMER entry is already
 *   queued so just increment the overrun count
 *
 * - return 1 if this signal is ignored by receiving process
 *
 * - return -1 if the task is marked exiting, so posix_timer_event
 *   can redirect it to the group leader
 *
 */

probe _signal.send.part3.return = kernel.function("send_sigqueue").return
{
    name = "send_sigqueueu"
    shared = 0
    send2queue = 1
}

/* probe signal.checkperm
 *
 *  check permissions for sending the signal
 *
 */
probe signal.checkperm = kernel.function("check_kill_permission")
{
    sig = $sig
    task = $t
    sinfo = $info
    name = "signal.checkperm"

    sig_name = _signal_name($sig)
    sig_pid = task_pid(task)
    pid_name = task_execname(task)

    if (sinfo == 2)
        si_code ="SIGSTOP or SIGKILL"
    else if (sinfo > 0)
        si_code="SI_KERNEL (SIGFPE, SIGSEGV, SIGTRAP, SIGCHLD, SIGPOLL)"
    else if (sinfo <= 0)
        si_code="SI_USER or SI_TIMER or SI_ASYNCIO"
}  

probe signal.checkperm.return = kernel.function("check_kill_permission").return
{
    name = "signal.checkperm"
    retstr = returnstr(1)
}
	

/* probe signal.wakeup
 *
 * Wake up the process for new active signals.
 *
 * Argument:
 *  sig_pid: pid of the process to be woke up
 *  pid_name: name of the process to be woke up
 *  resume: indicate whether to wake up a task in STOPPED or 
            TRACED state
 *  state_mask: a string representation indicates the mask 
 *              of task states that can be woken 
 */
probe signal.wakeup = kernel.function("signal_wake_up")
{
    sig_pid = $t->pid
    pid_name = kernel_string($t->comm)
    resume   = $resume
    if (resume == 0) {
        state_mask = "TASK_INTERRUPTIBLE"
    } else {
        state_mask = "TASK_INTERRUPTIBLE | TASK_STOPPED | TASK_TRACED"
    }
}


/* probe signal.ignored
 *
 *  Checks whether the signal is ignored or not.
 *
 */
probe signal.check_ignored = kernel.function("sig_ignored")
{
    sig_pid = $t->pid
    pid_name = kernel_string($t->comm)
    sig = $sig
    sig_name = _signal_name($sig)
}

probe signal.check_ignored.return = kernel.function("sig_ignored").return
{
    name = "sig_ignored"
    retstr = returnstr(1)
}


/* probe signal.handle_stop
 *
 *  For now, just comment it out since at the time handle_stop_signal()
 *  is called, it doesn't know whether current signal is STOP/COUNT. 
 *  So the calling of handle_stop_signal() doesn't mean that the Kernel
 *  is now processing the STOP/COUNT signal
 *
 */
/*
probe signal.handle_stop = kernel.function("handle_stop_signal")
{
    sig_pid = $p->pid
    pid_name = kernel_string($p->comm)
    sig_info = $sig
    sig_name = _signal_name($sig)
}
*/


/* probe signal.force_segv
 *
 *  Forces SIGSEGV when there are some issues while handling signals for the process.
 *
 */
probe signal.force_segv = kernel.function("force_sigsegv")
{
    sig_pid = $p->pid
    pid_name = kernel_string($p->comm)
    sig = $sig
    sig_name = _signal_name($sig)
}

probe signal.force_segv.return = kernel.function("force_sigsegv").return
{
    name = "force_sigsegv"
    retstr = returnstr(1)
}


/* probe signal.syskill
 *
 *  To kill a process, Pass the pid and signal to kill the process.
 *
 */
probe signal.syskill = syscall.kill
{
    sig_name = _signal_name($sig)
}

probe signal.syskill.return = syscall.kill.return
{
}


/* probe signal.sys_tgkill
 *
 *  Sends a signal to one specific thread.
 *
 */
probe signal.systgkill = syscall.tgkill
{
    sig_name = _signal_name($sig)
}

probe signal.systgkill.return = syscall.tgkill.return
{
}


/* probe signal.sys_tkill
 *
 *  Sends a signal to one specific task.
 *
 */
probe signal.systkill = syscall.tkill
{
    sig_name = _signal_name($sig)
}

probe signal.systkill.return = syscall.tkill.return
{
}


/* probe signal.send_sig_queue
 *
 * Queue signal to a process.
 *
 */
probe signal.send_sig_queue =
        kernel.function("send_sigqueue"),
        kernel.function("send_group_sigqueue")
{
    sig = $sig
    sig_name = _signal_name($sig)
    sig_pid = $p->pid
    pid_name = kernel_string($p->comm)
    sigqueue_addr = $q
}

probe signal.send_sig_queue.return =
        kernel.function("send_sigqueue").return,
        kernel.function("send_group_sigqueue").return
{
    retstr = returnstr(1)
}


/* probe signal.pending
 *
 * Used to examine the set of signals that are pending for 
 * delivery to the calling thread
 *
 * long do_sigpending(void __user *set, unsigned long sigsetsize)
 */
probe signal.pending = kernel.function("do_sigpending")
{
    sigset_add=$set
    sigset_size=$sigsetsize
}

probe signal.pending.return = kernel.function("do_sigpending").return
{
    retstr = returnstr(1)
}


/* probe signal.handle
 *
 * Used to invoke signals
 *
 * static int handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 *					sigset_t *oldset, struct pt_regs * regs)
 * Argument :-
 *  sig    : Signal number
 *  sinfo  : address of siginfo table.
 *  ka_addr : Address of the k_sigaction table associated with the signal
 *  oldset_addr : Address of a bit mask array of blocked signals
 *  regs   : Address in the Kernel Mode stack area 
 *  
 */
probe signal.handle = kernel.function("handle_signal")?,
        kernel.inline("handle_signal")?
{
    sig = $sig
    sig_name = _signal_name($sig)
    sinfo = $info
    sig_code = $info->si_code
    ka_addr = $ka
    oldset_addr =$oldset
    regs = $regs

    // Check whether the signal is a User Mode or Kernel mode Signal.
    
    if (sinfo == 0 && sig_code <= 0)
        sig_mode = "User Mode Signal"
    else if (sinfo >=  1)
        sig_mode = "Kernel Mode Signal"
}

probe signal.handle.return = kernel.function("handle_signal").return
{
    retstr = returnstr(1)
}


/* probe signal.do_action
 *
 * Fires by calling thread to examine and change a signal action
 *
 * int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
 *
 * Argument :-
 *  sig    : Signal number
 *  sigact_addr  : address of the new sigaction struct associated with the signal
 *  oldsigact_addr : address of a previous sigaction struct associated with the signal
 */
probe signal.do_action = kernel.function("do_sigaction")
{
    sig = $sig
    sigact_addr = $act
    oldsigact_addr = $oact
    if(sigact_table != 0)
    {
         sa_handler = $act->sa->sa_handler
         sa_mask = $act->sa->sa_mask
    }
}

probe signal.do_action.return = kernel.function("do_sigaction").return
{
    retstr = returnstr(1)
}


/* probe signal.procmask
 *
 * Fires by calling thread to examine and change blocked signals
 *
 * int sigprocmask(int how, sigset_t *set, sigset_t *oldset)
 *
 * Argument :-
 *  how : indicates how to change the blocked signals. Possible
 *        values are SIG_BLOCK=0 for blocking signals, SIG_UNBLOCK=1
 *        for unblocking signals, and SIG_SETMASK=2 for setting
 *        the signal mask
 *  sigset_addr : address of sigset_t to be set
 *  oldsigset_addr : address of the old sigset_t
 *  sigset : the actual sigset to be set
 *
 */
probe signal.procmask = kernel.function("sigprocmask")
{
    how=$how
    sigset_addr = $set
    oldsigset_addr = $oldset
    sigset = get_sigset($set)
}

function get_sigset:long(sigset:long) %{ /* pure */

    sigset_t *sigset = (sigset_t *)((long)THIS->sigset);

if(_NSIG_BPW == 64)
    THIS->__retvalue = deref(sizeof(sigset_t), sigset);
else if(_NSIG_BPW == 32)
    THIS->__retvalue = deref(sizeof(int), &(sigset->sig[0])) |
        ((u_int64_t)deref(sizeof(int), &(sigset->sig[1])))<<32;

    if(0)  {
deref_fault:
        CONTEXT->last_error = "pointer deref error";
    }
%}

probe signal.procmask.return = kernel.function("sigprocmask").return
{
    retstr = returnstr(1)
}


/*
 * probe signal.flush
 * 
 * Flush all pending signals for a task.
 *
 * void flush_signals(struct task_struct *t)
 *
 */
probe signal.flush = kernel.function("flush_signals")
{
    task = $t
    sig_pid = $t->pid
    pid_name = kernel_string($t->comm)
} 

Anon7 - 2021