Folks,
apologies for starting with a disclaimer that I''m not on this
alias. There are so many aliases and so little time ....
I''ve been kernel profiling for several years gleaning useful
performance insights from kernel call stacks as reported by lockstat.
on S8 and S9 and still perservere with lockstat as the format is
unchanged.
Yesterday I wanted to look inside some user code; a stripped binary
with a very small primary text segment, but with many text segments
mapped via unstripped shared shared libraries. A quick profile of
ustacks showed that there were no stack frames where the caller
could not be symbolically expressed. (Admittedly, there were
noise-level ocurrences of some addresses expressed as hex, and I''m
very picky about call stack quality in profiling tools).
Having the data tempted me to process it, so I knocked up an awk
aggregation script. I did a few quick Web searches for anything
similar that was preexisting but did not find anything. There''s
no point in reinventing the wheel, which is why I''m sharing these
crude and fairly trivial yet useful scripts.
Readers will appreciate these scripts could be readily applied
to kernel profiling by reversing the sense of the usr/kernel logic
on arg0/1, substituting stack() for ustack() and "(usermode)" for
"kernelmode". Which explains the funky way I process the stack
frames to ensure a unique list of functions and avoid multiple
billing of functions that commonly appear more than once (e.g. putnext,
biodone). I did not see any recursion in this user code, but you may
as well anticipate it.
up.d takes one argument, the pid you wish to profile. Redirect output
to a file and ^C to terminate the profiling.
up.inclexcl takes one argument, the file captured, and outputs the
inclusive (gprof-style) and exclusive (flat, prof-style) sample costs
attributed to each function. Sorry, I never made the script print
headings, but they obviously are:
Inclusive Exclusive
Function nsamples pct nsamples pct
# ./up.inclexcl up.out | more
_lwp_start 33730 63.11% 0 0.00%
_sseDevPollIO 23619 44.19% 419 0.78%
(kernelmode) 19473 36.43% 19473 36.43%
igmServicePointCall 11123 20.81% 222 0.42%
httpRequestRecv 9775 18.29% 24 0.04%
_httpRequestRecvHeader 9715 18.18% 54 0.10%
_ttpDispatcher 9501 17.78% 533 1.00%
httpResponseSend 6247 11.69% 116 0.22%
httpResponseRecv 5733 10.73% 55 0.10%
httpfilterReqHdrRecv 5481 10.26% 26 0.05%
httpResponseRecvHeader 4689 8.77% 54 0.10%
malloc_internal 4380 8.20% 2123 3.97%
listElements 4335 8.11% 163 0.30%
mutex_unlock 4143 7.75% 4141 7.75%
_filterObject 3955 7.40% 68 0.13%
httpRequestFinish 3837 7.18% 34 0.06%
igmServiceFunctionCall 3812 7.13% 18 0.03%
mutex_lock_impl 3798 7.11% 3798 7.11%
Enjoy!
Paul
-------------- next part --------------
#!/usr/sbin/dtrace -qs
BEGIN {
start = timestamp;
}
profile:::profile-479
/pid == $1 && arg0/
{
kernel++;
}
profile:::profile-479
/pid == $1 && arg1/
{
@a["!",ustack(50)] = count();
}
END {
elapsed = timestamp - start;
printf("%d.%09d seconds elapsed\n", elapsed/1000000000,
elapsed%1000000000);
printa(@a);
printf("!\n");
printf("(kernelmode)\n%d\n", kernel);
printf("!\n");
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/x-sun-shell-script
Size: 657 bytes
Desc: up.inclexcl
URL:
<http://mail.opensolaris.org/pipermail/dtrace-discuss/attachments/20060406/7dfe5427/attachment.bin>