To be safe, you should take Adam's advice one level further and not
execute the copyin until the connect return.  If the structure is not
faulted-in memory, the DIF code will hiccup because it can't take an
interrupt for the page-in.  And don't forget to clear all thread-local
variables when you are done with them.

So something like:

---8<---

typedef struct {
        char p[8];
} to_t;

syscall::connect:entry
{
        self->to = arg1;
}

syscall::connect:return
{
        trace(((to_t *)copyin(self->to, sizeof (to_t)))->p[3]);
        self->to = 0;
}

---8<---

Chip

> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:dtrace-discuss-
> [EMAIL PROTECTED] On Behalf Of Adam Leventhal
> Sent: Wednesday, June 04, 2008 2:34 PM
> To: Christophe Kalt
> Cc: [email protected]
> Subject: Re: [dtrace-discuss] What is wrong with this code?
> 
> Hi Christophe,
> 
> The copyin() action will copy its data to scratch space which is
> allocated
> only for the duration of a probe firing. Once you get to the return
> probe, the
> data that self->to points to may have been overwritten. You can solve
> this by
> making self->to a larger structure that actually contains the relevant
> data
> rather a pointer:
> 
> ---8<---
> 
> typedef struct {
>       char p[8];
> } to_t;
> 
> syscall::connect:entry
> {
>       self->to = *(to_t *)copyin(arg1, sizeof (to_t));
> }
> 
> syscall::connect:return
> {
>       trace(self->to.p[3]);
> }
> 
> ---8<---
> 
> Adam
> 
> 
> On Wed, Jun 04, 2008 at 07:01:54AM -0700, Christophe Kalt wrote:
> > syscall::connect:entry
> > {
> >   self->to  = (char *) copyin(arg1, arg2);
> >   self->ftp = ( self->to[0] == 0 && self->to[1] == 2 && self->to[3]
> == 21 ) ? 1 : 0;
> >   self->ugh = ( self->to[0] != 0 || self->to[1] != 2 );
> > }
> >
> > syscall::connect:return
> > / self->ftp /
> > {
> >   printf("%-20Y %s %d %s %.2x%.2x port=%d %d.%d.%d.%d\n",
> >          walltimestamp, zonename, uid, execname,
> >          self->to[0], self->to[1],
> >          self->to[3], self->to[4], self->to[5], self->to[6], self-
> >to[7]);
> > }
> >
> > In the printf, self->to contents aren't always what they were when
> the variable was assigned.  Why not?
> >
> > (Incidentally, i've fixed this by changing the code to the
following,
> but i'm curious as to what was wrong above.
> >
> > syscall::connect:entry
> > {
> >   to = (char *) copyin(arg1, arg2);
> >   self->ftp = ( to[0] == 0 && to[1] == 2 && to[3] == 21 ) ? 1 : 0;
> >   self->ugh = ( to[0] != 0 || to[1] != 2 );
> > }
> >
> > syscall::connect:entry
> > / self->ftp /
> > {
> >   to = (char *) copyin(arg1, arg2);
> >   printf("%-20Y %s %d %s %.2x%.2x port=%d %d.%d.%d.%d %s\n",
> >          walltimestamp, zonename, uid, execname,
> >          to[0], to[1],
> >          to[3], to[4], to[5], to[6], to[7],
> >          curpsinfo->pr_psargs);
> > }
> >
> > Also, is there a better way to write the above?  (Not so interested
> in the fbt connect_entry stuff.)
> >
> >
> > --
> > This message posted from opensolaris.org
> > _______________________________________________
> > dtrace-discuss mailing list
> > [email protected]
> 
> --
> Adam Leventhal, Fishworks                     http://blogs.sun.com/ahl
> _______________________________________________
> dtrace-discuss mailing list
> [email protected]


_______________________________________________
dtrace-discuss mailing list
[email protected]

Reply via email to