Hey Rich,

> I've written about 1000 lines of D code (using lots of cpp),
> in order to generate parsable logs of system activity.  The
> output format looks like:
> 
> syscall={
>   func=13'open_nocancel'
>   pid=9171
>   ppid=8738
>   time=63505036663689
>   av={
>     path=40'/dev/dtracehelper'
>     oflag=0
>     mode=438
>   }
>   rv=3
> }
> 
> For the curious, the format is Boulder IO with counted
> strings.  I came up with this format in order to keep D
> from needing to escape oddball characters, etc.
> 
> 
> The problem is, sometimes the code acts in peculiar ways.
> Most of the time, it prints (correctly):
> 
>     path=17'/dev/dtracehelper'
> 
> But sometimes (as in the output format example), it prints:
> 
>     path=40'/dev/dtracehelper'
> 
> 
> I suspect that someone here can help me find the bug (and
> most likely, in the process, teach me some D lore :-).  I
> certainly hope so...
> 
> 
> FYI, the code below was generated by some macros.  I then
> edited the white space a bit for this posting.  Consequently,
> it may look a bit odd in spots.  Try to ignore that detail...
> 
> -r
> 
> 
> syscall::open*:entry  {
>   self->arg2   = arg2;
>   self->arg1   = arg1;
>   self->arg0   = arg0;
>   self->follow = 1;
> }
> 
> syscall::open*:return /self->follow != 0/ {
>   printf("\n");
>   printf("syscall={\n");
>   func_l = strlen(probefunc);
>   printf("  func=%d'%s'\n", func_l,  probefunc);
>   printf("  pid=%d\n",      pid);
>   printf("  ppid=%d\n",     curpsinfo->pr_ppid);
>   printf("  time=%d\n",     timestamp);
>   printf("  av={\n");
> 
>   path   = copyinstr(self->arg0);
>   path_l = strlen(path);
>   printf("    path=%d'%s'\n", path_l, path);
> 
>   printf("    oflag=%d\n",    self->arg1);
>   printf("    mode=%d\n",     self->arg2);
>   printf("  }\n");
>   printf("  rv=%d\n",  arg0);
>   printf("}\n");
> }

You're using globals to hold the path and path length -- so you're 
occasionally getting the wrong answer when you're racing with another
thread executing open on another CPU.  To rectify this, use clause-local
variables:

        this->func_l = strlen(probefunc);
        ...
        this->path = copyinstr(self->arg0);
        this->path_l = strlen(path);
        ...

See the DTrace documentation on clause-local variables for details:

  http://wikis.sun.com/display/DTrace/Variables#Variables-ClauseLocalVariables

(It's so nice to be able to send out URLs to chapter and verse in the docs!
Thank you, wiki!)

        - Bryan

--------------------------------------------------------------------------
Bryan Cantrill, Sun Microsystems FishWorks.       http://blogs.sun.com/bmc
_______________________________________________
dtrace-discuss mailing list
[email protected]

Reply via email to