I have a clause that look like this: syscall::write:entry /execname == "ntpd" && self->recspec/ { speculate(self->recspec); printf(" fd=%d buf=%d\n%s",arg0,arg2, stringof(copyin(arg1,arg2-1))); } The ntpd program always write a \n trminated string in this context, so I used the "arg2-1" to drop the \n. This works fine about 90% of the time, but every once in a while, the printf prints out more data than arg2 specified. It gets the expected data okay, but tacked onto it is another 50 chars or so of random data that looks is in the same format as the regular data, but started in the middle of a line. Here are two examples: Good: 1 => write 2005 Aug 12 14:19:22.788629 fd=14 buf=126 53594 65962.803 129.159.201.1 10.8.117.25 3332859562.708790600 3332859562.701704979 3332859562.701952934 3332859562.802738400 Bad: 1 => write 2005 Aug 12 14:19:22.778629 fd=14 buf=127 53594 65962.790 129.149.247.58 10.8.117.25 3332859562.708947400 3332859562.695185661 3332859562.695643425 3332859562.78935840043585284 0.167939793 0.018730305 0.00161981400 Looking at the data some more, and I see that the data seems to be coming from a subsequent write call. Even if the sequence is such that by the time dtrace did the copyin the memory now had the new data, shouldn''t the string of and copyin have prevented it from being displayed? -- blu Remember when SOX compliant meant they were both the same color? ---------------------------------------------------------------------- Brian Utterback - OP/N1 RPE, Sun Microsystems, Inc. Ph:877-259-7345, Em:brian.utterback-at-ess-you-enn-dot-kom
On Fri, Aug 12, 2005 at 02:38:29PM -0400, Brian Utterback wrote:> I have a clause that look like this: > > syscall::write:entry > /execname == "ntpd" && self->recspec/ > { > speculate(self->recspec); > printf(" fd=%d buf=%d\n%s",arg0,arg2, > stringof(copyin(arg1,arg2-1))); > } > > The ntpd program always write a \n trminated string in this > context, so I used the "arg2-1" to drop the \n. > > This works fine about 90% of the time, but every once in a while, > the printf prints out more data than arg2 specified. It gets the > expected data okay, but tacked onto it is another 50 chars or so > of random data that looks is in the same format as the regular > data, but started in the middle of a line.The problem is simple; you''re using stringof() on a non-NIL-terminated string. One way to handle this would be to zero-terminate it yourself: this->str = copyin(arg1, arg2); this->str[arg2 - 1] = 0; printf(..., stringof(this->str)); Another (which only works on snv_15 and later) is to use the two-argument version of copyinstr: printf(..., copyinstr(arg1, arg2)); which will truncate the string at the arg2nd character, as desired. Cheers, - jonathan> Looking at the data some more, and I see that the data seems to be > coming from a subsequent write call. Even if the sequence is such that > by the time dtrace did the copyin the memory now had the new data, > shouldn''t the string of and copyin have prevented it from being > displayed?stringof() just says "the data here should be interpreted as a string". It does nothing to ''\0''-terminate it. Cheers, - jonathan -- Jonathan Adams, Solaris Kernel Development
Jonathan Adams wrote:> On Fri, Aug 12, 2005 at 02:38:29PM -0400, Brian Utterback wrote:[snip]> this->str = copyin(arg1, arg2); > this->str[arg2 - 1] = 0; > printf(..., stringof(this->str)); > > Another (which only works on snv_15 and later) is to use the two-argument > version of copyinstr: > > printf(..., copyinstr(arg1, arg2)); > > which will truncate the string at the arg2nd character, as desired. > > Cheers, > - jonathan > > >>Looking at the data some more, and I see that the data seems to be >>coming from a subsequent write call. Even if the sequence is such that >>by the time dtrace did the copyin the memory now had the new data, >>shouldn''t the string of and copyin have prevented it from being >>displayed? > > > stringof() just says "the data here should be interpreted as a string". It > does nothing to ''\0''-terminate it. > > Cheers, > - jonathan >I am now getting an error on the suggested line: this->str[arg2 - 1] = 0; Dtrace complains that one is a "void *" and the other is "int64_t". I am also confused by this result from my previous version. I understand that stringof cannot know how many chars to put in the string, but I got this example straight from the book, and it was supposed to fix exactly the problem I am having, i.e. printing extra stuff at the end of a write syscall. Is that a bug in the book? -- blu Remember when SOX compliant meant they were both the same color? ---------------------------------------------------------------------- Brian Utterback - OP/N1 RPE, Sun Microsystems, Inc. Ph:877-259-7345, Em:brian.utterback-at-ess-you-enn-dot-kom
On Mon, Aug 15, 2005 at 03:15:16PM -0400, Brian Utterback wrote:> I am now getting an error on the suggested line: > this->str[arg2 - 1] = 0; > Dtrace complains that one is a "void *" and the > other is "int64_t".You can declare that this->str is a pointer to a char or cast the result of the copyin to a char *.> I am also confused by this result from my previous > version. I understand that stringof cannot know how > many chars to put in the string, but I got this example > straight from the book, and it was supposed to fix exactly > the problem I am having, i.e. printing extra stuff at the > end of a write syscall. Is that a bug in the book?This sounds like a bug in the book in that we don''t gracefully handle strings which aren''t null-terminated. We''ll fix that in the next revision. Adam -- Adam Leventhal, Solaris Kernel Development http://blogs.sun.com/ahl