DTrace and Stack Size limitation

Submitted by smithuns on Sun, 11/11/2007 - 11:37pm. ::

During the Code Camp we organize in Germany, one of our ISVs had a particular need to determine the stack size of a multi-threaded application and from that information, restrict the stack size.

The stackdepth variable is not the key to the problem we are looking at. To get the stack size, one could use an one-liner:

dtrace -n 'on-cpu { @[execname] = max(curthread->t_procp->p_stksize); }'

For multithreaded programs, this would fail for apparent reasons. We are not taking the self variable into consideration, which would make the collected data erroneouw. We are not using any king of thread locality here. So, the solution we are looking for is something like this:

#!/usr/sbin/dtrace -s
this uintptr_t stkinfoptr;
this uintptr_t stkptr;

sched:::on-cpu, profile:::profile-997{
this->stkinfoptr = 0;
this->stkptr = 0;
}

sched:::on-cpu, profile:::profile-997
/execname != "sched"/{
this->stkinfoptr = curthread->t_lwp->lwp_ustack;
this->stkptr = (uintptr_t)0;
}

sched:::on-cpu, profile:::profile-997
/this->stkinfoptr != 0 && curpsinfo->pr_dmodel == PR_MODEL_ILP32/{
this->stkinfo32 = *(stack32_t *)copyin(this->stkinfoptr,
sizeof (stack32_t));
this->stktop = (uintptr_t)this->stkinfo32.ss_sp +this->stkinfo32.ss_size;
this->stkptr = (uintptr_t)uregs[R_SP];
}

sched:::on-cpu, profile:::profile-997
/this->stkinfoptr != 0 && curpsinfo->pr_dmodel == PR_MODEL_LP64/{
this->stkinfo = *(stack_t *)copyin(this->stkinfoptr,
sizeof (stack_t));
this->stktop = (uintptr_t)this->stkinfo.ss_sp +this->stkinfo.ss_size;
this->stkptr = (uintptr_t)uregs[R_SP];
}

sched:::on-cpu, profile:::profile-997
/this->stkptr != 0/{
@a[execname] = quantize(this->stktop - this->stkptr);
}

dtrace:::ERROR{
@b[execname] = count();
}

dtrace:::END{
printa(@a);
printf("\nErrors: \n" ) ;
printa(" %@d %s\n", @b);
}

This approach works. I tried executing this script on my x64 (Opteron) workstation as well as on SPARC platform running Solaris 10 Update 4.