Hi,

I think your observation is true. You could also say that the script
doesn't handle the case of connect(2) failure. It always assumes that
connect(2) succeeds. Anyway, I think you could fix this by using
associative an array instead of thread local variable to keep which process
is using which file descriptor, and other associative arrays to maintain
socket information. This of course comes with more expense, because
accessing associative arrays is more expensive that thread local variables.
I have modified the script to look as below. Still I am not satisfied
because it doesn’t handle the case when a process exits without closing its
file descriptors.



#!/usr/sbin/dtrace -s

#pragma D option quiet
#pragma D option switchrate=10hz

/* If AF_INET and AF_INET6 are "Unknown" to DTrace, replace with numbers: */
inline int af_inet = AF_INET;
inline int af_inet6 = AF_INET6;

dtrace:::BEGIN
{
        printf("  %-6s %-16s %-3s %-16s %-5s %s\n", "PID", "PROCESS", "FAM",
            "ADDRESS", "PORT", "DURATION(sec)");
}

syscall::connect*:entry
{
        self->saddr = arg1;
        self->s = (struct sockaddr_in *)copyin(self->saddr, sizeof (struct
sockaddr));
        self->f = self->s->sin_family;
        self->fd = arg0;
}

syscall::connect*:return
/arg0 == 0 && (self->f == af_inet || self->f == af_inet6)/
{
        self->s = (struct sockaddr_in *)copyin(self->saddr, sizeof (struct
sockaddr));
        family[pid, self->fd] = self->f;
        port[pid, self->fd] = ntohs(self->s->sin_port);
        address[pid, self->fd] = inet_ntop(self->s->sin_family,
            (void *)&self->s->sin_addr);
        start[pid, self->fd] = timestamp;
        self->saddr;
        self->f = 0;
        self->s = 0;
        self->fd = 0;

}

syscall::close:entry
/start[pid, arg0]/
{
        this->delta = (timestamp - start[pid, arg0]) / 1000;
        this->sec = this->delta / 1000000;
        this->ms = (this->delta - (this->sec * 1000000)) / 1000;
        printf("  %-6d %-16s %-3d %-16s %-5d %d.%03d\n", pid, execname,
            family[pid, arg0], address[pid, arg0], port[pid, arg0],
            this->sec, this->ms);
        family[pid, arg0] = 0;
        address[pid, arg0] = 0;
        port[pid, arg0] = 0;
        start[pid, arg0] = 0;
}


---
BR,
Mohamed A. Khalfella


On Mon, Apr 7, 2014 at 10:22 AM, 肖楠 <xiaonan19830...@qq.com> wrote:

> Hi, all:
>
>     I am studying Dtrace now, and have read the soclose.d(http://www.
> dtracebook.com/index.php/Network_Lower_Level_Protocols:soclose.d).
>   Per my understanding, because this script use "self" variable, it works
> only if the same thread connects and closes the socket. If one thread
> connects the socket, while the other closes it, this script can't detect
> it. Is it right? Thanks in advance!
>
> Best Regards
> Nan Xiao
>
> *dtrace-discuss* | 
> Archives<https://www.listbox.com/member/archive/184261/=now>
> <https://www.listbox.com/member/archive/rss/184261/22309886-fdd6ce82> |
> Modify<https://www.listbox.com/member/?&;>Your Subscription
> <http://www.listbox.com>
>



-- 
BR,
Mohamed A. Khalfella



-------------------------------------------
dtrace-discuss
Archives: https://www.listbox.com/member/archive/184261/=now
RSS Feed: https://www.listbox.com/member/archive/rss/184261/25769126-e243886f
Modify Your Subscription: 
https://www.listbox.com/member/?member_id=25769126&id_secret=25769126-8d47a7b2
Powered by Listbox: http://www.listbox.com

Reply via email to