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>