Mathias,
You''ve on the right track, but you''ve got a number of basic
things
wrong. Here''s an improved version of your script ...
syscall::recvfrom:entry
/pid != $pid && (execname == $$1 || ($$1 == "" &&
execname != "dtrace"))/
{
self->in = 1;
printf("%Y: ", walltimestamp);
self->arg0 = arg0; /* int s */
self->arg1 = arg1; /* void *buf */
self->arg2 = arg2; /* size_t len */
self->arg3 = arg3; /* int flags */
self->arg4 = arg4; /* struct sockaddr *from */
self->arg5 = arg5; /* socklen_t *fromlen */
printf("%s(PID:%d) called %s", execname, pid, probefunc);
printf("(s=%d, buf=\"%S\", len=%d)\n",
arg0, stringof(copyin(arg1, arg2)), arg2);
}
syscall::recvfrom:return
/self->in/
{
printf("%Y: ", walltimestamp);
printf("%s(PID:%d) returned %s", execname, pid, probefunc);
printf("(s=%d, buf=\"%S\", len=%d) => %d
(errno=%d)\n",
self->arg0,
stringof(copyin(self->arg1, self->arg2)),
self->arg2,
arg0,
errno);
self->len = *(socklen_t *) copyin((uintptr_t)self->arg5,
sizeof(socklen_t));
self->socks = (struct sockaddr *) copyin((uintptr_t)self->arg4,
self->len);
self->hport = (uint_t)(self->socks->sa_data[0]);
self->lport = (uint_t)(self->socks->sa_data[1]);
self->hport <<= 8;
self->port = self->hport + self->lport;
printf("Port number: %d\n", self->port);
printf("IP address: %d.%d.%d.%d\n",
self->socks->sa_data[2],
self->socks->sa_data[3],
self->socks->sa_data[4],
self->socks->sa_data[5]);
printf("======\n");
self->in = 0;
}
Your code wasn''t thread safe because you were using global variables
(I''ve added more self-> prefixes), and you weren''t matching
entry and
return probes (I''ve added the customary "self->in" gate
which also saves
you from a return probe firing first and simplifies the return probe
predicate).
It may be possible to improve your entry probe predicate, but not
knowing how you intend to use the script, I thought I''d leave that well
alone.
I''m not claiming that this is the definitive implementation, and there
may be other bugs which others can spot, but the above is a more correct
version of what I think you intended.
Your main bug, was to forget that fromlen is a pointer, which means you
also need to copyin() the fromlen value before you can use it.
Hope this helps,
Phil
Mathias Koerber wrote:> I am new to Dtrace, so bear with me...
>
> I am trying to debug a problem where outgoing (reply) UDP packets are
> apparently lost from a server, though I have good reason to believe that
> the daemon actually sends them, but they may get routed on the wrong
> interface, or lost elsewhere.
>
> To verify this, but in order to avoid the high impact truss may have,
> I am trying to write a Dtrace script that logs all network
> activity. Note that this is for SOlaris 10, so I have no ip provider or
> such available.
>
>
> However, after many iterations I am not getting past some errors which
> are leaving me baffled:
>
> Here is the script I tried:
>
>
>> BEGIN
>> {
>> printf("tracing starts at %d=%Y\n",
timestamp,walltimestamp);
>> }
>>
>> END
>> {
>> printf("tracing ends at %d\n", timestamp);
>> }
>>
>> syscall::recvfrom:entry
>> /pid != $pid && (execname == $$1 || ($$1 == ""
&& execname != "dtrace"))/
>> {
>> printf("%Y: ", walltimestamp);
>>
>> self->desc = (int ) arg0; /* file descriptor passed to write()
*/
>> self->bufp = (uintptr_t) arg1; /* buffer pointer passed to
write() */
>> self->size = (size_t) arg2; /* size, in bytes passed to write()
*/
>> self->flags = (int) arg3; /* flags */
>> self->from = (struct sockaddr *) arg4;
>> self->fromlen = (socklen_t *) arg5;
>>
>> printf("%s(PID:%d) called %s(rc=%d)
(socket=%d,\nbuf=\"%S\"\n size=%d) => err=%d\n", execname,
pid, probefunc, arg0,
>> self->desc,
>> stringof(copyin(self->bufp, self->size)),
>> self->size,
>> errno);
>> }
>>
>>
>>
>> syscall::recvfrom:return
>> /pid != $pid && (execname == $$1 || ($$1 == ""
&& execname != "dtrace"))/
>> {
>> printf("%Y: ", walltimestamp);
>>
>> printf("%s(PID:%d) returned %s(rc=%d)
(socket=%d,\nbuf=\"%S\"\n size=%d) => err=%d\n", execname,
pid, probefunc, arg0,
>> self->desc,
>> stringof(copyin(self->bufp, (ssize_t)arg0)),
>> self->size,
>> errno);
>>
>
> ** Note, since the size of the buffer is returned in
> the returncode, I am using arg0 here to copy that data into the
> kernel.
>
>
>> printf("self->from = 0x%x\n", (long) self->from);
>> printf("self->fromlen = 0x%x\n", (long) self->fromlen);
>>
>> socks = (struct sockaddr *) copyin( (uintptr_t)self->from,
*((socklen_t *)self->fromlen) );
>>
>
> ** similarly, the fromlen parameter points to the size of the
> address-structure returned... So is the above correct?
>
>
>> hport = (uint_t)(socks->sa_data[0]);
>> lport = (uint_t)(socks->sa_data[1]);
>> hport <<= 8;
>> port = hport + lport;
>> printf("Port number: %d\n", port);
>>
>> printf("IP address: %d.%d.%d.%d\n", socks->sa_data[2],
>> socks->sa_data[3],
>> socks->sa_data[4],
>> socks->sa_data[5]);
>> printf("======\n");
>>
>> self->desc = 0;
>> self->bufp = 0;
>> self->size = 0;
>> self->flags = 0;
>> self->from = 0;
>> self->fromlen = 0;
>> self->sock = 0;
>> }
>>
>
>
>
> However, calling this to trace the process ''v'' I get:
>
>
>> # dtrace -q -s v.d v
>> tracing starts at 488313267882683=2009 Nov 15 23:32:43
>> 2009 Nov 15 23:32:45: v(PID:657) called recvfrom(rc=12) (socket=12,
>> buf="\0"
>> size=4000) => err=0
>> dtrace: error on enabled probe ID 4 (ID 43897:
syscall::recvfrom:return): invalid address (0xfffffd7ffdf18c8c) in action #12 at
DIF offset 8
>> 2009 Nov 15 23:32:45: v(PID:657) called recvfrom(rc=12) (socket=12,
>> buf="\004\227\001\0"
>> size=4000) => err=0
>> dtrace: error on enabled probe ID 4 (ID 43897:
syscall::recvfrom:return): out of scratch space in action #7 at DIF offset 40
>> ^C
>> tracing ends at 488317440553167
>>
>
> Why am I getting out of scratch-space?
>
> And where does the invalid address come from? I am specifically not
> trying to access the data in the user-process but using copyin to copy
> it for dtrace access, but why am I getting this problem ?
>
> Any help is appreciated.
>
> I had a look at the Dtrace tools like dtruss etc, but there
doesn''t seem
> to be one that monitors a processes detailed network traffic. If there
> is I would appreciate a pointer
>
> Thanks
> M
>
> _______________________________________________
> dtrace-discuss mailing list
> dtrace-discuss at opensolaris.org
>