On Mon, Aug 04, 2008 at 11:27:37PM +0200, St?phane Payrard wrote:
> disclaimer: I am a dtrace beginner.
> A common convention in Umix is that a process rereads its
> configuration files when sent
> a SIGHUP signal. So I thought smart to write a dtrace script (shown
> below) that prints the files opened
> by a process that receive any signal.  I starts the said script, next
> I do a "sudo killall -1 httpd" and I get nothing except  lines like :
> 
> trace: error on enabled probe ID 2 (ID 17602: syscall::open:entry):
> invalid user access in predicate at DIF offset 4
> dtrace: error on enabled probe ID 3 (ID 17603: syscall::open:return):
> invalid user access in predicate at DIF offset 4
> 
> I am using leopard.
> What am I doing wrong?

There are a couple basic issues with your code:

1.  "this->" variables are only guaranteed to keep their values during
    a single firing (i.e. for any number of blocks with the *same* probe
    definition).  For your purposes, either "self->" (thread-local" or
    global associative arrays make more sense.

2.  The "postsig" part of proc::postsig:signal-handle is a private
    implementation detail, and should be removed;  that way, your script
    will also work under Solaris.

3.  copyin actions are only likely to succeed if they happen after a known
    user or kernel reading of the data;  i.e. it's better to do the copyinstr()
    in the *return* probe.

Your original program:
> #! /usr/sbin/dtrace -s
> 
> proc::postsig:signal-handle  {
>   this->pid = pid;
>   printf("%s with pid %d got a signal %d\n", execname, pid, arg0);
> }
> syscall::open:entry /this->pid == pid/ {   this->file = copyinstr(arg0);  }
> syscall::open:return /this->pid == pid/ {   printf( "%s  %s %d\n",
> execname,  this->file, arg0); }

How I'd do it:

--- cut here ---
#!/usr/sbin/dtrace -qs

proc:::signal-handle
{
    gotsignal[pid] = 1;
    printf("%s with pid %d got a signal %d\n", execname, pid, arg0);
}

syscall::open:entry
/gotsignal[pid]/
{
     self->file = arg0;
}

syscall::open:return
/self->file/
{
        printf("%s  %s %d\n", execname, copyinstr(self->file), arg0);
        self->file = 0;
}

proc:::exit
/gotsignal[pid]/
{
        gotsignal[pid] = 0;
}
--- cut here ---

(the last part cleans up old state as processes exit)

Cheers,
- jonathan

_______________________________________________
dtrace-discuss mailing list
[email protected]

Reply via email to