#!/usr/sbin/dtrace -s /* ** anonprofile.d - snoop process anonymous memory reservation as it occurs. ** Written in DTrace (Solaris 10 x86 build 51). ** ** 18-May-2004, ver 0.60 (early release, check for newer versions) ** ** ** USAGE: ./anonprofile.d ** ** Different styles of output can be selected by changing ** the "PFORMAT" variable below. ** ** FIELDS: ** UID user ID ** PID process ID ** PPID parent process ID ** TOTAL total size of anon mem usage, bytes ** SIZE size of anon mem resv or unresv, bytes ** ARGS command (full arguments) ** TIME timestamp, us ** ** SEE ALSO: pmap ** ** NOTE: private kernel structures are read, this script may not work on ** newer builds of Solaris 10. ** ** Standard Disclaimer: This is freeware, use at your own risk. ** ** 18-May-2004 Brendan Gregg Created this. ** */ inline int PFORMAT = 1; /* 1 - Default output ** 2 - Timestamp output (includes TIME) ** 3 - Everything, space delimited (for spreadsheets) */ #pragma D option quiet /* ** Print header */ dtrace:::BEGIN /PFORMAT == 1/ { printf("%5s %5s %9s %s\n","UID","PID","TOTAL","ARGS"); } dtrace:::BEGIN /PFORMAT == 2/ { printf("%-14s %5s %5s %9s %s\n", "TIME","UID","PID","TOTAL","ARGS"); } dtrace:::BEGIN /PFORMAT == 3/ { printf("%s %s %s %s %s %s %s\n", "TIME","UID","PID","PPID","TOTAL","SIZE","ARGS"); } /* ** Main */ fbt:genunix:anon_resvmem:entry /arg1 != 0/ { /* Store values for a reservation of anon mem */ self->size = arg0; self->uid = curpsinfo->pr_euid; self->pid = pid; self->ppid = curpsinfo->pr_ppid; self->args = (char *)curpsinfo->pr_psargs; } fbt:genunix:anon_resvmem:return /total[pid] == 0 && self->args != NULL && arg1 != 0/ { /* Increment total anon mem if successful */ total[self->pid] = self->size; self->ok = 1; } fbt:genunix:anon_resvmem:return /total[pid] != 0 && self->args != NULL && arg1 != 0 && ! self->ok/ { /* Increment total anon mem if successful */ total[self->pid] += self->size; self->ok = 1; } fbt:genunix:anon_unresv:entry /total[pid] > 0/ { /* Decrement anon mem for unreservations */ self->size = - arg0; self->uid = curpsinfo->pr_euid; self->pid = pid; self->ppid = curpsinfo->pr_ppid; self->args = (char *)curpsinfo->pr_psargs; total[pid] += self->size; self->ok = 1; } /* ** Print output */ fbt:genunix:anon_resvmem:return, fbt:genunix:anon_unresv:entry /PFORMAT == 1 && self->ok/ { printf("%5d %5d %9d %s\n", self->uid,self->pid,total[self->pid],stringof(self->args)); } fbt:genunix:anon_resvmem:return, fbt:genunix:anon_unresv:entry /PFORMAT == 2 && self->ok/ { printf("%-14d %5d %5d %9d %s\n", timestamp/1000,self->uid,self->pid, total[self->pid],stringof(self->args)); } fbt:genunix:anon_resvmem:return, fbt:genunix:anon_unresv:entry /PFORMAT == 3 && self->ok/ { printf("%d %d %d %d %d %d %s\n", timestamp/1000,self->uid,self->pid,self->ppid, total[self->pid],self->size,stringof(self->args)); } /* ** Cleanup */ fbt:genunix:anon_resvmem:return, fbt:genunix:anon_unresv:entry /self->ok/ { self->size = 0; self->ok = 0; self->pid = 0; self->ppid = 0; self->uid = 0; self->args = NULL; } syscall::rexit:entry { total[pid] = 0; }