Alan Hargreaves's Weblog

Even More DTrace Lab Answers (9 & 10)

Alan Hargreaves
Senior Principal Technical Support Engineer

OK, let's get the rest out.

Exercise 9

List the processes that are connecting to a specific port.

OK, we'll take that to mean we want to know the name and the process ID of connections to a particular port. This requires just a little network programming knowledge. We can see that the second argument (arg1) to connect(3SOCKET) is a sockaddr. The extra knowledge that we need is that to get a port, we need to cast it to a sockaddr_in and look at the port structure element. This bit of code expects the command line argument 1 to be a port number.

#!/usr/sbin/dtrace -s
#pragma D option quiet
syscall::connect:entry {

this->sock = (struct sockaddr_in \*)copyin(arg1, arg2);

self->port = this->sock->sin_port;
syscall::connect:entry /self->port == $1/ {

printf("%5d %s\\n", pid, execname); }
syscall::connect:entry { self->port = 0; }

Exercise 10

Write a script to show where a specific system call, rename for example, is blocking and how long it is blocked for.

This one was a bit of fun to write, especially since the output format specifier for a stack is not documented and I had to find it in dt_printf.c.

We'll use the sched provider in this. While it would be nice to use the wakeup probe, it's not fired from the thread context so we won't have the thread local variable that we need to check and use. So, we just use on-cpu, which will tell us how long we were off cpu since we were told to block. Note that this also means that we are not tracking normal scheduling where it may have been pre-empted by another thread for whatever reason. This is what we want.

#!/usr/sbin/dtrace -s
#pragma D option quiet
BEGIN { printf("Collecting... \^C to continue\\n"); }
syscall::rename:entry {self->interest = 1; }
sched:::sleep /self->interest/ { self->blocktime = timestamp; }
sched:::on-cpu /self->blocktime/ {

this->taken = timestamp - self->blocktime;

@[curthread,stack()] = quantize(this->taken);

self->blocktime = 0;
syscall::rename:return { self->interest = 0; }
END { printa("Thread 0x%p %k %@d\\n", @); }

This leaves us with only Exercise 11 to go. I'll try to get that up tomorrow.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.