public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* RE: Tapset for Signals....
@ 2006-08-04  0:21 Stone, Joshua I
  2006-08-16  8:34 ` Li Guanglei
  0 siblings, 1 reply; 11+ messages in thread
From: Stone, Joshua I @ 2006-08-04  0:21 UTC (permalink / raw)
  To: Manoj S Pattabhiraman, systemtap

[-- Attachment #1: Type: text/plain, Size: 3159 bytes --]

On Wednesday, August 02, 2006 9:27 PM, Manoj S Pattabhiraman wrote:
> I have updated the signal tapset, with the functions you have asked
> for. Since i would not be able to send it to the maillist, please
> post this mail.
> 
> Lemme know your suggestions ..

Sorry I have not had time to look at this before.  I have reviewed your
tapset now and I have some suggestions.  Some of the changes I went
ahead and made myself, for which I have attached a new version.  This
tapset can replace the process.signal_* probes when it is completed.

* Misc. formatting: I've made the indentation consistent throughout the
file, and some other small changes.  Nothing major, I'm just picky.  :)

* Naming: this is more of a general pet-peeve that I have with some of
the new tapsets.  There is no reason to name the probepoint exactly like
the function it represents.  Unlike kernel function-naming, we have the
flexibility to express hierarchy in the names.  To take a specific
example, you have an alias named "signal.sendsig".  The trailing "sig"
is redundant -- this would be better named "signal.send".

* signal.send: I did a lot of digging for this to try to capture all of
the paths where signals can be sent.  The attached "send_signal.pdf"
shows the callgraph as I found it.  Those 4 marked in blue are the
points that I chose to probe for "process.send_signal".  The advantage
to probing them separately is that I can expose a 'shared' variable that
indicates whether the signal is going to a specific thread or the entire
thread group.  The functions marked in red are those that can generate
STOP/KILL signals, which I haven't found a convenient way to probe
(perhaps static markers?).

* handle_signal: I have seen this function sometimes inlined, so this
needs to be conditional.

* signal.ignored: Your comment correctly states that this is really a
_check_ whether a signal is ignored, but the name is misleading.  I
would suggest something like "signal.check_ignored".

* handle_stop_signal: Your comment says "fires when a stop signal is
sent", but this is incorrect.  This function is called to _check_
whether this signal is a stop/cont, and if so take special action.
Thus, this will get called for almost every signal, many of which will
not be stop signals. 

* syscall duplication: some of your probes are duplicating points from
the syscall tapset (signal.syskill, etc.).  Do we really need these?  If
you really want these, it would be preferable to make use of the syscall
tapset, e.g.:
	probe signal.syskill = syscall.kill

* signal.send_sig_queue: This is not needed with the change I made to
signal.send, correct?  Consider removing if this is redundant.

* argstr:  These arg-strings are very specific to a format that _you_
would like.  If you look at the syscall tapset, you'll notice that the
arg-strings are very generic, simply a comma-delimited list of the
function arguments.  I'm not sure that what you've provided is as
useful...

My suggested changes are attached.  Please review my comments and
changes, and feel free to rebut any of the above.

Thanks,

Josh

[-- Attachment #2: send_signal.pdf --]
[-- Type: application/octet-stream, Size: 6887 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Tapset for Signals....
  2006-08-04  0:21 Tapset for Signals Stone, Joshua I
@ 2006-08-16  8:34 ` Li Guanglei
  0 siblings, 0 replies; 11+ messages in thread
From: Li Guanglei @ 2006-08-16  8:34 UTC (permalink / raw)
  To: Stone, Joshua I; +Cc: Manoj S Pattabhiraman, systemtap

Hi Josh,

Below are my questions while I am trying to add signal trace hooks 
into LKET:

Stone, Joshua I wrote:
> * signal.send: I did a lot of digging for this to try to capture all of
> the paths where signals can be sent.  The attached "send_signal.pdf"
> shows the callgraph as I found it.  Those 4 marked in blue are the
> points that I chose to probe for "process.send_signal".  The advantage
> to probing them separately is that I can expose a 'shared' variable that
> indicates whether the signal is going to a specific thread or the entire
> thread group.  The functions marked in red are those that can generate
> STOP/KILL signals, which I haven't found a convenient way to probe
> (perhaps static markers?).

1. group_send_sig_info() will check the permissions for sending the 
signal before calling __group_send_sig_info(). So probing 
__group_send_sig_info() will omit the situation that a signal has been 
actually sent out but was rejected due to wrong permission.

But __group_send_sig_info() will be also called by the following 
functions besides group_send_sig_info(),:
   1> do_notify_parent() when a process exits
   2> check_process_timers() for POSIX timers
   3> do_notify_parent_cldstop()
   4> kill_proc_info_as_uid()

So which one do you prefer to probe, __group_send_sig_info or 
group_send_sig_info?


2. send_sigqueue() and send_group_sigqueue() is only used for POSIX 
timers. If we choose to probe them, then I think it's better to add a 
local variable like "send_to_queue=1" to indicate that the signal is 
generated by posix timers. Then by looking at "send_to_queue" and 
"shared" local variables, we can determine which function actually 
triggers the probe handler.

> * handle_stop_signal: Your comment says "fires when a stop signal is
> sent", but this is incorrect.  This function is called to _check_
> whether this signal is a stop/cont, and if so take special action.
> Thus, this will get called for almost every signal, many of which will
> not be stop signals. 

Yes. You are right. But the comment is still unchanged. :-)

> 
> * syscall duplication: some of your probes are duplicating points from
> the syscall tapset (signal.syskill, etc.).  Do we really need these?  If
> you really want these, it would be preferable to make use of the syscall
> tapset, e.g.:
> 	probe signal.syskill = syscall.kill

Yes. Agree.

- Guanglei

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: Tapset for Signals....
@ 2006-08-17 16:24 Stone, Joshua I
  0 siblings, 0 replies; 11+ messages in thread
From: Stone, Joshua I @ 2006-08-17 16:24 UTC (permalink / raw)
  To: Manoj S Pattabhiraman, systemtap; +Cc: guanglei

On Thursday, August 17, 2006 6:42 AM, Manoj S Pattabhiraman wrote:
> Hi *,
> 
> Find the updated signal tapset,
> 
>         1. As per the suggestions, i have removed the argstr from the
> probe points.
>         2. Added some checks to find whether the signals generated are
> USER or Kernel Mode in signal_handle probe.
> 
> I will start the work on Man pages (stapprobes) and the test script,
> once the signal tapset is finalised/completed.
> 
> Since i dont have cvs write access, can some one commit the latest
> signal tapset to cvs.

Done.

> And also please lemme know whats the procedure for getting write
> access to cvs.

The form is here:
http://sources.redhat.com/cgi-bin/pdw/ps_form.cgi


Josh

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Tapset for Signals....
  2006-08-17  9:30   ` Li Guanglei
@ 2006-08-17 13:37     ` Manoj S Pattabhiraman
  0 siblings, 0 replies; 11+ messages in thread
From: Manoj S Pattabhiraman @ 2006-08-17 13:37 UTC (permalink / raw)
  To: systemtap; +Cc: Stone, Joshua I, guanglei

[-- Attachment #1: Type: text/plain, Size: 6645 bytes --]

Hi *,

Find the updated signal tapset,

        1. As per the suggestions, i have removed the argstr from the 
probe points.
        2. Added some checks to find whether the signals generated are 
USER or Kernel Mode in signal_handle probe.

I will start the work on Man pages (stapprobes) and the test script, once 
the signal tapset is finalised/completed.

Since i dont have cvs write access, can some one commit the latest signal 
tapset to cvs. And also please lemme know 
whats the procedure for getting write access to cvs.



Please review and lemme know your suggestions.

Thanks & Regards,    Manoj
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Manoj S Pattabhiraman, ADTools, Linux on zSeries, Ph : +91 80 51776449 T/L 
 92 46951, e-mail: mpattabh@in.ibm.com



Li Guanglei <guanglei@cn.ibm.com> 
08/17/2006 03:02 PM

To
systemtap@sourceware.org
cc
"Stone, Joshua I" <joshua.i.stone@intel.com>, Manoj S 
Pattabhiraman/India/IBM@IBMIN
Subject
Re: Tapset for Signals....






I committed the following changes based on our discussion:

   1. add "send2queue" and "name" variable for signal.send.part*
   2. add signal.send.return probe alias
   3. add signal.checkperm and signal.checkperm.return probe alias
   4. comment out signal.handle_stop
   5. alias all signal syscalls to syscall tapsets.

- Guanglei

Li Guanglei wrote:
> Stone, Joshua I wrote:
>> On Wednesday, August 16, 2006 1:36 AM, Li Guanglei wrote:
>>> Below are my questions while I am trying to add signal trace hooks
>>> into LKET:
>>
>> Thanks for reviewing.
>>
>>> 1. group_send_sig_info() will check the permissions for sending the
>>> signal before calling __group_send_sig_info(). So probing
>>> __group_send_sig_info() will omit the situation that a signal has been
>>> actually sent out but was rejected due to wrong permission.
>>>
>>> But __group_send_sig_info() will be also called by the following
>>> functions besides group_send_sig_info(),:
>>>    1> do_notify_parent() when a process exits
>>>    2> check_process_timers() for POSIX timers
>>>    3> do_notify_parent_cldstop()
>>>    4> kill_proc_info_as_uid()
>>>
>>> So which one do you prefer to probe, __group_send_sig_info or
>>> group_send_sig_info?
>>
>> I prefer __group_signal_sig_info, because it catches the additional
>> signals that you noted.  Also, consider the parallel case of
>> specific_send_sig_info, which is called by sys_tkill and sys_tgkill. In
>> that case, the permission check happens in the sys_* functions, before
>> specific_send_sig_info is called.  Thus on that path we are only
>> capturing the signals that will actually be sent (though possibly
>> ignored).
>>
> 
> Yes. Since do_tkill will also call check_kill_permission before calling 
> specific_send_sig_info(), __group_send_sig_info() looks more like a 
> parallel of specific_send_sig_info() than group_send_sig_info().
> 
>> This establishes a pretty consistent view of what signal.send means: if
>> a process successfully sends a signal, that will trigger signal.send.
>> Signals that are rejected because of permissions will return a failure
>> to the sender, and thus shouldn't trigger signal.send.  Signals that 
are
>> ignored will still report success to the sender, even though the
>> recipient dropped it on the floor, so it should trigger signal.send.
> 
> Yes. From the source codes, sending signal will return success(0) even 
> if it is ignored or is a duplication of an existing signal in the 
> pending queue. And it will return failure if failed permission checking.
> 
> So I agree with you that __group_send_sig_info() is a more suitable 
> probe point than group_send_sig_info().  Thanks for your suggestion.
> 
>>
>> If you want to find signals that are rejected due to permissions, then 
a
>> different probe point will be needed, like perhaps a return probe on
>> check_kill_permissions.
> 
> Yes. I am considering adding signal.check_perm. It will also probe the 
> entry of check_kill_permissions() to get more info about the signals 
> besides the return value.
> 
>>
>>> 2. send_sigqueue() and send_group_sigqueue() is only used for POSIX
>>> timers. If we choose to probe them, then I think it's better to add a
>>> local variable like "send_to_queue=1" to indicate that the signal is
>>> generated by posix timers. Then by looking at "send_to_queue" and
>>> "shared" local variables, we can determine which function actually
>>> triggers the probe handler.
>>
>> Ok, that's a good suggestion.
>>
>>>> * handle_stop_signal: Your comment says "fires when a stop signal is
>>>> sent", but this is incorrect.  This function is called to _check_
>>>> whether this signal is a stop/cont, and if so take special action.
>>>> Thus, this will get called for almost every signal, many of which
>>>> will not be stop signals.
>>> Yes. You are right. But the comment is still unchanged. :-)
>>
>> Indeed -- I didn't take it on myself to fix *all* of my gripes.  :)  I
>> didn't fix this one because I'm not convinced that it's needed, or what
>> useful information can be gotten from probing handle_stop_signal.  If
>> you really want, we could make a probe that does what the comment says,
>> something like this:
> 
> Yes. I see. At the time that 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.send_stop = signal.send {
>>     if (sig != SIGSTOP) next;
>> }
>>
>> But users can do this themselves without much trouble, and with better
>> granularity.  It doesn't make sense for us to enumerate send_stop,
>> send_cont, send_int, etc., when the user can just check the sig value
>> manually.
> 
> Yes. The user can just look at the sig variable in signal.send to get 
> enough information.
> 
>>
>>>> * syscall duplication: some of your probes are duplicating points
>>>> from the syscall tapset (signal.syskill, etc.).  Do we really need
>>>> these?  If you really want these, it would be preferable to make use
>>>>     of the syscall tapset, e.g.: probe signal.syskill = syscall.kill
>>> Yes. Agree.
>>
>> Agree that they're not needed?  Or do you want the latter, where we 
keep
>> the probepoint, but alias it to the syscall tapset.
> 
> I don't have a obvious preference towards whether to keep or remove 
> them. I just think that keeping and alias them to syscall tapset will be 

> a little convenient when a user want to trace only the signal 
activities.
> 
> - Guanglei



[-- Attachment #2: signal.stp --]
[-- Type: application/octet-stream, Size: 10606 bytes --]

// 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
 *  task - a task handle to the signal recipient
 *  shared - indicates whether this signal is shared by the thread group
 */
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.
 *
 */
probe signal.wakeup = kernel.function("signal_wake_up")
{
    sig_pid = $t->pid
    pid_name = kernel_string($t->comm)
    state   = $resume
    if (state == 0) {
        sig_state = "TASK_INTERRUPTIBLE"
    } else {
        sig_state = "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_info = $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_info = $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_info = $sig
    sig_name = _signal_name($sig)
    sig_pid = $p->pid
    pid_name = kernel_string($p->comm)
    user_id = $q->uid
    nos_process = $q->processes
    nos_pending_sig = $q->sigpending
}

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


/* probe signal.pend
 *
 * Used to Suspend signals
 *
 * long do_sigpending(void __user *set, unsigned long sigsetsize)
 */
probe signal.pend = kernel.function("do_sigpending")
{
    uspace_add=$set
    sset_size=$sigsetsize
}

probe signal.pend.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
 *  info   : address of siginfo table.
 *  ka     : Address of the k_sigaction table associated with the signal
 *  oldset : 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_addr = $info
    sig_code = $info->si_code
    sig_stack_add=$ka
    bitmask_add=$oldset
    kernmode_stack_add=$regs

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

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


/* probe signal.do_action
 *
 * Called by sys_sigaction() to copy the new new_ka table into the entry at the sig-1 position.
 *
 * int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
 *
 * Argument :-
 *  sig    : Signal number
 *  act    : Address of the sigaction table associated with the signal
 *  oact   : Address of a previous sigaction table
 *
 */
probe signal.do_action = kernel.function("do_sigaction")
{
    sig = $sig
    sigact_table=$act
    psigact_table=$oact
}

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


/* probe signal.procmask
 *
 * Allows processes to modify the set of blocked signals.
 *
 * int sigprocmask(int how, sigset_t *set, sigset_t *oldset)
 *
 * Argument :-
 *  how    : Flag having one of the values (SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK)
 *  set    : Address of the process address space to a bit array.
 *  oldset : Address of the process address space where the previous bit mask must be stored.
 *
 */
probe signal.procmask = kernel.function("sigprocmask")
{
    stemp=$how
    sigset=$set
    sigoset=$oldset

    if (stemp == 0)
        sig_how ="SIG_BLOCK"
    else if (stemp ==  1)
        sig_how="SIG_UNBLOCK"
    else if (stemp == 2)
        sig_how="SIG_SETMASK"
}

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)
} 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Tapset for Signals....
  2006-08-17  1:50 ` Li Guanglei
@ 2006-08-17  9:30   ` Li Guanglei
  2006-08-17 13:37     ` Manoj S Pattabhiraman
  0 siblings, 1 reply; 11+ messages in thread
From: Li Guanglei @ 2006-08-17  9:30 UTC (permalink / raw)
  To: systemtap; +Cc: Stone, Joshua I, Manoj S Pattabhiraman

I committed the following changes based on our discussion:

   1. add "send2queue" and "name" variable for signal.send.part*
   2. add signal.send.return probe alias
   3. add signal.checkperm and signal.checkperm.return probe alias
   4. comment out signal.handle_stop
   5. alias all signal syscalls to syscall tapsets.

- Guanglei

Li Guanglei wrote:
> Stone, Joshua I wrote:
>> On Wednesday, August 16, 2006 1:36 AM, Li Guanglei wrote:
>>> Below are my questions while I am trying to add signal trace hooks
>>> into LKET:
>>
>> Thanks for reviewing.
>>
>>> 1. group_send_sig_info() will check the permissions for sending the
>>> signal before calling __group_send_sig_info(). So probing
>>> __group_send_sig_info() will omit the situation that a signal has been
>>> actually sent out but was rejected due to wrong permission.
>>>
>>> But __group_send_sig_info() will be also called by the following
>>> functions besides group_send_sig_info(),:
>>>    1> do_notify_parent() when a process exits
>>>    2> check_process_timers() for POSIX timers
>>>    3> do_notify_parent_cldstop()
>>>    4> kill_proc_info_as_uid()
>>>
>>> So which one do you prefer to probe, __group_send_sig_info or
>>> group_send_sig_info?
>>
>> I prefer __group_signal_sig_info, because it catches the additional
>> signals that you noted.  Also, consider the parallel case of
>> specific_send_sig_info, which is called by sys_tkill and sys_tgkill.  In
>> that case, the permission check happens in the sys_* functions, before
>> specific_send_sig_info is called.  Thus on that path we are only
>> capturing the signals that will actually be sent (though possibly
>> ignored).
>>
> 
> Yes. Since do_tkill will also call check_kill_permission before calling 
> specific_send_sig_info(), __group_send_sig_info() looks more like a 
> parallel of specific_send_sig_info() than group_send_sig_info().
> 
>> This establishes a pretty consistent view of what signal.send means: if
>> a process successfully sends a signal, that will trigger signal.send.
>> Signals that are rejected because of permissions will return a failure
>> to the sender, and thus shouldn't trigger signal.send.  Signals that are
>> ignored will still report success to the sender, even though the
>> recipient dropped it on the floor, so it should trigger signal.send.
> 
> Yes. From the source codes, sending signal will return success(0) even 
> if it is ignored or is a duplication of an existing signal in the 
> pending queue. And it will return failure if failed permission checking.
> 
> So I agree with you that __group_send_sig_info() is a more suitable 
> probe point than group_send_sig_info().  Thanks for your suggestion.
> 
>>
>> If you want to find signals that are rejected due to permissions, then a
>> different probe point will be needed, like perhaps a return probe on
>> check_kill_permissions.
> 
> Yes. I am considering adding signal.check_perm. It will also probe the 
> entry of check_kill_permissions() to get more info about the signals 
> besides the return value.
> 
>>
>>> 2. send_sigqueue() and send_group_sigqueue() is only used for POSIX
>>> timers. If we choose to probe them, then I think it's better to add a
>>> local variable like "send_to_queue=1" to indicate that the signal is
>>> generated by posix timers. Then by looking at "send_to_queue" and
>>> "shared" local variables, we can determine which function actually
>>> triggers the probe handler.
>>
>> Ok, that's a good suggestion.
>>
>>>> * handle_stop_signal: Your comment says "fires when a stop signal is
>>>> sent", but this is incorrect.  This function is called to _check_
>>>> whether this signal is a stop/cont, and if so take special action.
>>>> Thus, this will get called for almost every signal, many of which
>>>> will not be stop signals.
>>> Yes. You are right. But the comment is still unchanged. :-)
>>
>> Indeed -- I didn't take it on myself to fix *all* of my gripes.  :)  I
>> didn't fix this one because I'm not convinced that it's needed, or what
>> useful information can be gotten from probing handle_stop_signal.  If
>> you really want, we could make a probe that does what the comment says,
>> something like this:
> 
> Yes. I see. At the time that 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.send_stop = signal.send {
>>     if (sig != SIGSTOP) next;
>> }
>>
>> But users can do this themselves without much trouble, and with better
>> granularity.  It doesn't make sense for us to enumerate send_stop,
>> send_cont, send_int, etc., when the user can just check the sig value
>> manually.
> 
> Yes. The user can just look at the sig variable in signal.send to get 
> enough information.
> 
>>
>>>> * syscall duplication: some of your probes are duplicating points
>>>> from the syscall tapset (signal.syskill, etc.).  Do we really need
>>>> these?  If you really want these, it would be preferable to make use
>>>>     of the syscall tapset, e.g.: probe signal.syskill = syscall.kill
>>> Yes. Agree.
>>
>> Agree that they're not needed?  Or do you want the latter, where we keep
>> the probepoint, but alias it to the syscall tapset.
> 
> I don't have a obvious preference towards whether to keep or remove 
> them. I just think that keeping and alias them to syscall tapset will be 
> a little convenient when a user want to trace only the signal activities.
> 
> - Guanglei

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Tapset for Signals....
  2006-08-17  1:03 Stone, Joshua I
@ 2006-08-17  1:50 ` Li Guanglei
  2006-08-17  9:30   ` Li Guanglei
  0 siblings, 1 reply; 11+ messages in thread
From: Li Guanglei @ 2006-08-17  1:50 UTC (permalink / raw)
  To: Stone, Joshua I; +Cc: Manoj S Pattabhiraman, systemtap

Stone, Joshua I wrote:
> On Wednesday, August 16, 2006 1:36 AM, Li Guanglei wrote:
>> Below are my questions while I am trying to add signal trace hooks
>> into LKET:
> 
> Thanks for reviewing.
> 
>> 1. group_send_sig_info() will check the permissions for sending the
>> signal before calling __group_send_sig_info(). So probing
>> __group_send_sig_info() will omit the situation that a signal has been
>> actually sent out but was rejected due to wrong permission.
>>
>> But __group_send_sig_info() will be also called by the following
>> functions besides group_send_sig_info(),:
>>    1> do_notify_parent() when a process exits
>>    2> check_process_timers() for POSIX timers
>>    3> do_notify_parent_cldstop()
>>    4> kill_proc_info_as_uid()
>>
>> So which one do you prefer to probe, __group_send_sig_info or
>> group_send_sig_info?
> 
> I prefer __group_signal_sig_info, because it catches the additional
> signals that you noted.  Also, consider the parallel case of
> specific_send_sig_info, which is called by sys_tkill and sys_tgkill.  In
> that case, the permission check happens in the sys_* functions, before
> specific_send_sig_info is called.  Thus on that path we are only
> capturing the signals that will actually be sent (though possibly
> ignored).
> 

Yes. Since do_tkill will also call check_kill_permission before 
calling specific_send_sig_info(), __group_send_sig_info() looks more 
like a parallel of specific_send_sig_info() than group_send_sig_info().

> This establishes a pretty consistent view of what signal.send means: if
> a process successfully sends a signal, that will trigger signal.send.
> Signals that are rejected because of permissions will return a failure
> to the sender, and thus shouldn't trigger signal.send.  Signals that are
> ignored will still report success to the sender, even though the
> recipient dropped it on the floor, so it should trigger signal.send.

Yes. From the source codes, sending signal will return success(0) even 
if it is ignored or is a duplication of an existing signal in the 
pending queue. And it will return failure if failed permission checking.

So I agree with you that __group_send_sig_info() is a more suitable 
probe point than group_send_sig_info().  Thanks for your suggestion.

> 
> If you want to find signals that are rejected due to permissions, then a
> different probe point will be needed, like perhaps a return probe on
> check_kill_permissions.

Yes. I am considering adding signal.check_perm. It will also probe the 
entry of check_kill_permissions() to get more info about the signals 
besides the return value.

> 
>> 2. send_sigqueue() and send_group_sigqueue() is only used for POSIX
>> timers. If we choose to probe them, then I think it's better to add a
>> local variable like "send_to_queue=1" to indicate that the signal is
>> generated by posix timers. Then by looking at "send_to_queue" and
>> "shared" local variables, we can determine which function actually
>> triggers the probe handler.
> 
> Ok, that's a good suggestion.
> 
>>> * handle_stop_signal: Your comment says "fires when a stop signal is
>>> sent", but this is incorrect.  This function is called to _check_
>>> whether this signal is a stop/cont, and if so take special action.
>>> Thus, this will get called for almost every signal, many of which
>>> will not be stop signals.
>> Yes. You are right. But the comment is still unchanged. :-)
> 
> Indeed -- I didn't take it on myself to fix *all* of my gripes.  :)  I
> didn't fix this one because I'm not convinced that it's needed, or what
> useful information can be gotten from probing handle_stop_signal.  If
> you really want, we could make a probe that does what the comment says,
> something like this:

Yes. I see. At the time that 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.send_stop = signal.send {
>     if (sig != SIGSTOP) next;
> }
> 
> But users can do this themselves without much trouble, and with better
> granularity.  It doesn't make sense for us to enumerate send_stop,
> send_cont, send_int, etc., when the user can just check the sig value
> manually.

Yes. The user can just look at the sig variable in signal.send to get 
enough information.

> 
>>> * syscall duplication: some of your probes are duplicating points
>>> from the syscall tapset (signal.syskill, etc.).  Do we really need
>>> these?  If you really want these, it would be preferable to make use
>>> 	of the syscall tapset, e.g.: probe signal.syskill = syscall.kill
>> Yes. Agree.
> 
> Agree that they're not needed?  Or do you want the latter, where we keep
> the probepoint, but alias it to the syscall tapset.

I don't have a obvious preference towards whether to keep or remove 
them. I just think that keeping and alias them to syscall tapset will 
be a little convenient when a user want to trace only the signal 
activities.

- Guanglei

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: Tapset for Signals....
@ 2006-08-17  1:03 Stone, Joshua I
  2006-08-17  1:50 ` Li Guanglei
  0 siblings, 1 reply; 11+ messages in thread
From: Stone, Joshua I @ 2006-08-17  1:03 UTC (permalink / raw)
  To: Li Guanglei; +Cc: Manoj S Pattabhiraman, systemtap

On Wednesday, August 16, 2006 1:36 AM, Li Guanglei wrote:
> Below are my questions while I am trying to add signal trace hooks
> into LKET:

Thanks for reviewing.

> 1. group_send_sig_info() will check the permissions for sending the
> signal before calling __group_send_sig_info(). So probing
> __group_send_sig_info() will omit the situation that a signal has been
> actually sent out but was rejected due to wrong permission.
> 
> But __group_send_sig_info() will be also called by the following
> functions besides group_send_sig_info(),:
>    1> do_notify_parent() when a process exits
>    2> check_process_timers() for POSIX timers
>    3> do_notify_parent_cldstop()
>    4> kill_proc_info_as_uid()
> 
> So which one do you prefer to probe, __group_send_sig_info or
> group_send_sig_info?

I prefer __group_signal_sig_info, because it catches the additional
signals that you noted.  Also, consider the parallel case of
specific_send_sig_info, which is called by sys_tkill and sys_tgkill.  In
that case, the permission check happens in the sys_* functions, before
specific_send_sig_info is called.  Thus on that path we are only
capturing the signals that will actually be sent (though possibly
ignored).

This establishes a pretty consistent view of what signal.send means: if
a process successfully sends a signal, that will trigger signal.send.
Signals that are rejected because of permissions will return a failure
to the sender, and thus shouldn't trigger signal.send.  Signals that are
ignored will still report success to the sender, even though the
recipient dropped it on the floor, so it should trigger signal.send.

If you want to find signals that are rejected due to permissions, then a
different probe point will be needed, like perhaps a return probe on
check_kill_permissions.

> 2. send_sigqueue() and send_group_sigqueue() is only used for POSIX
> timers. If we choose to probe them, then I think it's better to add a
> local variable like "send_to_queue=1" to indicate that the signal is
> generated by posix timers. Then by looking at "send_to_queue" and
> "shared" local variables, we can determine which function actually
> triggers the probe handler.

Ok, that's a good suggestion.

>> * handle_stop_signal: Your comment says "fires when a stop signal is
>> sent", but this is incorrect.  This function is called to _check_
>> whether this signal is a stop/cont, and if so take special action.
>> Thus, this will get called for almost every signal, many of which
>> will not be stop signals.
> 
> Yes. You are right. But the comment is still unchanged. :-)

Indeed -- I didn't take it on myself to fix *all* of my gripes.  :)  I
didn't fix this one because I'm not convinced that it's needed, or what
useful information can be gotten from probing handle_stop_signal.  If
you really want, we could make a probe that does what the comment says,
something like this:

probe signal.send_stop = signal.send {
    if (sig != SIGSTOP) next;
}

But users can do this themselves without much trouble, and with better
granularity.  It doesn't make sense for us to enumerate send_stop,
send_cont, send_int, etc., when the user can just check the sig value
manually.

>> * syscall duplication: some of your probes are duplicating points
>> from the syscall tapset (signal.syskill, etc.).  Do we really need
>> these?  If you really want these, it would be preferable to make use
>> 	of the syscall tapset, e.g.: probe signal.syskill = syscall.kill
> 
> Yes. Agree.

Agree that they're not needed?  Or do you want the latter, where we keep
the probepoint, but alias it to the syscall tapset.


Josh

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: Tapset for Signals....
@ 2006-08-10  0:45 Stone, Joshua I
  0 siblings, 0 replies; 11+ messages in thread
From: Stone, Joshua I @ 2006-08-10  0:45 UTC (permalink / raw)
  To: Manoj S Pattabhiraman; +Cc: systemtap

Manoj,

Just now I committed your signals tapset to CVS, with my changes as
well.  Some of my concerns below still need to be addressed, as well as
Frank's comments, but I figured that we should go ahead and put it in.
We can always improve on it going forward. :)

Josh


On Thursday, August 03, 2006 5:20 PM, Stone, Joshua I wrote:
> On Wednesday, August 02, 2006 9:27 PM, Manoj S Pattabhiraman wrote:
>> I have updated the signal tapset, with the functions you have asked
>> for. Since i would not be able to send it to the maillist, please
>> post this mail. 
>> 
>> Lemme know your suggestions ..
> 
> Sorry I have not had time to look at this before.  I have reviewed
> your tapset now and I have some suggestions.  Some of the changes I
> went ahead and made myself, for which I have attached a new version. 
> This tapset can replace the process.signal_* probes when it is
> completed. 
> 
> * Misc. formatting: I've made the indentation consistent throughout
> the file, and some other small changes.  Nothing major, I'm just
> picky.  :) 
> 
> * Naming: this is more of a general pet-peeve that I have with some of
> the new tapsets.  There is no reason to name the probepoint exactly
> like the function it represents.  Unlike kernel function-naming, we
> have the flexibility to express hierarchy in the names.  To take a
> specific example, you have an alias named "signal.sendsig".  The
> trailing "sig" is redundant -- this would be better named
> "signal.send". 
> 
> * signal.send: I did a lot of digging for this to try to capture all
> of the paths where signals can be sent.  The attached
> "send_signal.pdf" shows the callgraph as I found it.  Those 4 marked
> in blue are the points that I chose to probe for
> "process.send_signal".  The advantage to probing them separately is
> that I can expose a 'shared' variable that indicates whether the
> signal is going to a specific thread or the entire thread group.  The
> functions marked in red are those that can generate STOP/KILL
> signals, which I haven't found a convenient way to probe (perhaps
> static markers?). 
> 
> * handle_signal: I have seen this function sometimes inlined, so this
> needs to be conditional.
> 
> * signal.ignored: Your comment correctly states that this is really a
> _check_ whether a signal is ignored, but the name is misleading.  I
> would suggest something like "signal.check_ignored".
> 
> * handle_stop_signal: Your comment says "fires when a stop signal is
> sent", but this is incorrect.  This function is called to _check_
> whether this signal is a stop/cont, and if so take special action.
> Thus, this will get called for almost every signal, many of which will
> not be stop signals.
> 
> * syscall duplication: some of your probes are duplicating points from
> the syscall tapset (signal.syskill, etc.).  Do we really need these? 
> If you really want these, it would be preferable to make use of the
> syscall tapset, e.g.:
> 	probe signal.syskill = syscall.kill
> 
> * signal.send_sig_queue: This is not needed with the change I made to
> signal.send, correct?  Consider removing if this is redundant.
> 
> * argstr:  These arg-strings are very specific to a format that _you_
> would like.  If you look at the syscall tapset, you'll notice that the
> arg-strings are very generic, simply a comma-delimited list of the
> function arguments.  I'm not sure that what you've provided is as
> useful...
> 
> My suggested changes are attached.  Please review my comments and
> changes, and feel free to rebut any of the above.
> 
> Thanks,
> 
> Josh

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: Tapset for Signals....
@ 2006-08-04  0:22 Stone, Joshua I
  0 siblings, 0 replies; 11+ messages in thread
From: Stone, Joshua I @ 2006-08-04  0:22 UTC (permalink / raw)
  To: Manoj S Pattabhiraman, systemtap

[-- Attachment #1: Type: text/plain, Size: 179 bytes --]

On Thursday, August 03, 2006 5:20 PM, Stone, Joshua I wrote:
> My suggested changes are attached.

Of course, it helps if I actually *attach* the file to the email...

Josh

[-- Attachment #2: signal.stp --]
[-- Type: application/octet-stream, Size: 8195 bytes --]

// 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.
 *
 */

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"

    argstr = sprintf("Signal : %s - Process name : %s (%d) - Signal Code : %s",
                     sig_name, sig_pid, pid_name, si_code)
}

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

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

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

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

/* probe signal.wakeup
 *
 * Wake up the process for new active signals.
 *
 */

probe signal.wakeup = kernel.function("signal_wake_up")
{
    sig_pid = $t->pid
    pid_name = kernel_string($t->comm)
    state   = $resume
    if (state == 0) {
        sig_state = "TASK_INTERRUPTIBLE"
    } else {
        sig_state = "TASK_INTERRUPTIBLE | TASK_STOPPED | TASK_TRACED"
    }
    argstr = sprintf("Wakeup Signal to Process %s (%d) - Process State after the signal : %s",
                     pid_name, sig_pid, sig_state)
}

/* 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_info = $sig
    sig_name = _signal_name($sig)
    argstr = sprintf("Signal : %s is ignored by the Process : %s (%d)",
                     sig_name, pid_name, sig_pid)
}

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

/* probe signal.handle_stop
 *
 *  Fires when a stop signal is sent to a process.
 *
 */

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)
    argstr = sprintf("Handle_Stop_Signal : %s is sent to the process %s (%d)",
                     sig_name, pid_name, sig_pid);
}

/* 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_info = $sig
    sig_name = _signal_name($sig)
    argstr = sprintf("Signal < %d > is forced on to the process %s (%d)",
                     sig_name, pid_name, sig_pid);
}

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 = kernel.function("sys_kill")
{
    sig_pid = $pid
    sig_info = $sig
    argstr = sprintf("Process %d has recieved a Signal %s", sig_pid, sig_name);
}

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

/* probe signal.sys_tgkill
 *
 *  Sends a signal to one specific thread.
 *
 */

probe signal.systgkill = kernel.function("sys_tgkill")
{
    sig_tgid = $tgid
    sig_pid = $pid
    sig_info = $sig
    sig_name = _signal_name($sig)
    argstr = sprintf("Signal %s is sent to Process ID : %d under the Thread Group ID : %d",
                     sig_name, sig_pid, sig_tgid);
}

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


/* probe signal.sys_tkill
 *
 *  Sends a signal to one specific task.
 *
 */

probe signal.systkill = kernel.function("sys_tkill")
{
    sig_pid = $pid
    sig_info = $sig
    sig_name = _signal_name($sig)
    argstr = sprintf("Signal %s is sent to Process ID : %d", sig_name, sig_pid);
}

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

/* 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_info = $sig
    sig_name = _signal_name($sig)
    sig_pid = $p->pid
    pid_name = kernel_string($p->comm)
    user_id = $q->uid
    nos_process = $q->processes
    nos_pending_sig = $q->sigpending
}

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

/* probe signal.pend
 *
 * Used to Suspend signals
 *
 * long do_sigpending(void __user *set, unsigned long sigsetsize)
 */

probe signal.pend = kernel.function("do_sigpending")
{
    uspace_add=$set
    sset_size=$sigsetsize
}

probe signal.pend.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
 *  info   : address of siginfo table.
 *  ka     : Address of the k_sigaction table associated with the signal
 *  oldset : Address of a bit mask array of blocked signals
 *  regs   : Address in the Kernel Mode stack area w
 *
 */

probe signal.handle = kernel.function("handle_signal")?,
        kernel.inline("handle_signal")?
{
    sig = $sig
    sig_name = _signal_name($sig)
    siginfo_add=$info
    sig_stack_add=$ka
    bitmask_add=$oldset
    kernmode_stack_add=$regs
}

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

/* probe signal.do_action
 *
 * Called by sys_sigaction() to copy the new new_ka table into the entry at the sig-1 position.
 *
 * int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
 *
 * Argument :-
 *  sig    : Signal number
 *  act    : Address of the sigaction table associated with the signal
 *  oact   : Address of a previous sigaction table
 *
 */
probe signal.do_action = kernel.function("do_sigaction")
{
    sig = $sig
    siginfo_add=$info
    sig_stack_add=$ka
    bitmask_add=$oldset
    kernmode_stack_add=$regs
}

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

/* probe signal.procmask
 *
 * Allows processes to modify the set of blocked signals.
 *
 * int sigprocmask(int how, sigset_t *set, sigset_t *oldset)
 *
 * Argument :-
 *  how    : Flag having one of the values (SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK)
 *  set    : Address of the process address space to a bit array.
 *  oldset : Address of the process address space where the previous bit mask must be stored.
 *
 */

probe signal.procmask = kernel.function("sigprocmask")
{
    stemp=$how
    sigset=$set
    sigoset=$oldset

    if (stemp == 0)
        sig_how ="SIG_BLOCK"
    else if (stemp ==  1)
        sig_how="SIG_UNBLOCK"
    else if (sinfo == 2)
        sig_how="SIG_SETMASK"
}

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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Tapset for Signals....
  2006-08-03  4:24 Manoj S Pattabhiraman
@ 2006-08-03 15:01 ` Frank Ch. Eigler
  0 siblings, 0 replies; 11+ messages in thread
From: Frank Ch. Eigler @ 2006-08-03 15:01 UTC (permalink / raw)
  To: Manoj S Pattabhiraman; +Cc: systemtap


Manoj S Pattabhiraman <mpattabh@in.ibm.com> writes:

> I have updated the signal tapset, with the functions you have asked for.
> Since i would not be able to send it to the maillist, please post this
> mail.

Thank you.  A few observations may help complete the work:
- the probe points should be documented in the man page stapprobes.5
- the buildok test suite should be extended with a script that exercises
  all probe points
- within probes for functions that take siginfo structs, it may be handy
  if the probe handler extracted salient fields from the struct into
  local script variables, as users of these aliases won't be able to do
  that without referring to the raw $info symbol.

- FChE

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Tapset for Signals....
@ 2006-08-03  4:24 Manoj S Pattabhiraman
  2006-08-03 15:01 ` Frank Ch. Eigler
  0 siblings, 1 reply; 11+ messages in thread
From: Manoj S Pattabhiraman @ 2006-08-03  4:24 UTC (permalink / raw)
  To: systemtap

[-- Attachment #1: Type: text/plain, Size: 215 bytes --]

Hi,

I have updated the signal tapset, with the functions you have asked for.
Since i would not be able to send it to the maillist, please post this
mail.

Lemme know your suggestions ..



Thanks & Regards, 
Manoj

[-- Attachment #2: signal.stp --]
[-- Type: application/octet-stream, Size: 7685 bytes --]

// Signal tapset
// Copyright (C) 2006 IBM Corp.
//
// 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, Its better to filter the
//          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.sendsig
 *
 * Fires when a signal is sent to a process.
 * 
 */

 probe signal.sendsig = kernel.function("send_signal")
 {   
	sig=$sig
 	sig_name = _signal_name($sig)
	sinfo = $info
	sig_pid = $t->pid
	pid_name = kernel_string($t->comm)
	
	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" 	
	
	argstr = sprintf( "Signal : %s - Process name : %s (%d) - Signal Code : %s ", sig_name,sig_pid,pid_name,si_code)
}	

/* probe signal.wakeup
 *
 * Wake up the process for new active signals.
 *
 */

probe signal.wakeup =
        kernel.function("signal_wake_up")
{
   sig_pid = $t->pid
   pid_name = kernel_string($t->comm)
   state   = $resume
   if (state == 0)     {
                sig_state = "TASK_INTERRUPTIBLE"
         } else
                {
                sig_state = "TASK_INTERRUPTIBLE | TASK_STOPPED | TASK_TRACED"
        }
  argstr = sprintf( "Wakeup Signal to Process %s (%d) - Process State after the signal : %s ",pid_name,sig_pid,sig_state)	
}

/* probe signal.ignored
 *
 *  Checks whether the signal is ignored or not.
 *
 */

probe signal.ignored = kernel.function("sig_ignored")
 {
	sig_pid = $t->pid
	pid_name = kernel_string($t->comm) 
	sig_info = $sig
	sig_name = _signal_name($sig)
	argstr = sprintf( "Signal : %s is ignored by the Process : %s (%d) ",sig_name,pid_name,sig_pid)
 } 	

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

/* probe signal.handle_stopsig
 *
 *  Fires when a stop signal is sent to a process.
 *
 */

 probe signal.handle_stopsig = kernel.function("handle_stop_signal")
 {
        sig_pid = $p->pid
        pid_name = kernel_string($p->comm)
        sig_info = $sig
	sig_name = _signal_name($sig)
	argstr = sprintf(" Handle_Stop_Signal : %s is sent to the process %s (%d)",sig_name,pid_name,sig_pid);
}

/* probe signal.forcesig
 *
 *  Forces SIGSEV when there are some issues while handling signals for the process.
 * 
 */

probe signal.forcesig = kernel.function("force_sigsegv")
 {
        sig_pid = $p->pid
        pid_name = kernel_string($p->comm)
        sig_info = $sig
	sig_name = _signal_name($sig)
        argstr = sprintf("Signal < %d > is forced on to the process %s (%d)",sig_name,pid_name,sig_pid);
}

probe signal.forcesig.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 = kernel.function("sys_kill")
 {
        sig_pid = $pid
        sig_info = $sig
        argstr = sprintf("Process %d has recieved a Signal %s ",sig_pid,sig_name);
}

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

/* probe signal.sys_tgkill
 *
 *  Sends a signal to one specific thread.
 *
 */

probe signal.systgkill = kernel.function("sys_tgkill")
 {
	sig_tgid = $tgid
        sig_pid = $pid
        sig_info = $sig
	sig_name = _signal_name($sig)
        argstr = sprintf(" Signal %s is sent to Process ID : %d under the Thread Group ID : %d",sig_name,sig_pid,sig_tgid);
}

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


/* probe signal.sys_tkill
 *
 *  Sends a signal to one specific task.
 *
 */

probe signal.systkill = kernel.function("sys_tkill")
 {
        sig_pid = $pid
        sig_info = $sig
	sig_name = _signal_name($sig)
        argstr = sprintf("Signal %s is sent to Process ID : %d ",sig_name,sig_pid);
}

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

/* 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_info = $sig
    sig_name = _signal_name($sig)	
    sig_pid = $p->pid
    pid_name = kernel_string($p->comm)
    user_id = $q->uid
    nos_process = $q->processes
    nos_pending_sig = $q->sigpending			
}

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

/* probe signal.sigpend
 *
 * Used to Suspend signals 
 *
 * long do_sigpending(void __user *set, unsigned long sigsetsize)
 :*/

probe signal.sigpend = kernel.function("do_sigpending")
{
	uspace_add=$set 
	sset_size=$sigsetsize
}

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


/* probe signal.handsig
 *
 * 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
 *  info   : address of siginfo table.	
 *  ka     : Address of the k_sigaction table associated with the signal
 *  oldset : Address of a bit mask array of blocked signals
 *  regs   : Address in the Kernel Mode stack area w
 *
 */

probe signal.handlesig = kernel.function("handle_signal")
{
	sig = $sig
	siginfo_add=$info
   	sig_stack_add=$ka
	bitmask_add=$oldset
	kernmode_stack_add=$regs
}

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

/* probe signal.dosig_action
 *
 * Called by sys_sigaction() to copy the new new_ka table into the entry at the sig-1 position. 
 *
 * int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
 *
 * Argument :-
 *  sig    : Signal number
 *  act    : Address of the sigaction table associated with the signal
 *  oact   : Address of a previous sigaction table
 *
 */
probe signal.dosig_action = kernel.function("do_sigaction")
{
        sig = $sig
        siginfo_add=$info
        sig_stack_add=$ka
        bitmask_add=$oldset
        kernmode_stack_add=$regs
}

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

/* probe signal.sigprocmask
 *
 * Allows processes to modify the set of blocked signals.
 *
 * int sigprocmask(int how, sigset_t *set, sigset_t *oldset)
 *
 * Argument :-
 *  how    : Flag having one of the values (SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK)
 *  set    : Address of the process address space to a bit array.
 *  oldset : Address of the process address space where the previous bit mask must be stored.
 *
 */

probe signal.sigprocmask = kernel.function("sigprocmask")
{
	stemp=$how
	sigset=$set
	sigoset=$oldset

        if (stemp == 0)
                sig_how ="SIG_BLOCK"
        else if (stemp ==  1)
                sig_how="SIG_UNBLOCK"
        else if (sinfo == 2)
                sig_how="SIG_SETMASK"
}

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



^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2006-08-17 16:24 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-08-04  0:21 Tapset for Signals Stone, Joshua I
2006-08-16  8:34 ` Li Guanglei
  -- strict thread matches above, loose matches on Subject: below --
2006-08-17 16:24 Stone, Joshua I
2006-08-17  1:03 Stone, Joshua I
2006-08-17  1:50 ` Li Guanglei
2006-08-17  9:30   ` Li Guanglei
2006-08-17 13:37     ` Manoj S Pattabhiraman
2006-08-10  0:45 Stone, Joshua I
2006-08-04  0:22 Stone, Joshua I
2006-08-03  4:24 Manoj S Pattabhiraman
2006-08-03 15:01 ` Frank Ch. Eigler

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).