1 #!/usr/pkg/bin/perl -w 2 # 3 # hotkernel - sample on-CPU kernel-level functions and modules. 4 # Written using Perl and DTrace (Solaris 10 03/05) 5 # 6 # This samples the on-CPU function at 1001 Hertz, for a simple yet 7 # effective kernel-level profiling tool for sampling exclusive function time. 8 # The output will identify which function is on the CPU the most - which is 9 # the hottest. See Notes/ALLexclusive_notes.txt for an explanation of 10 # exclusive time. 11 # 12 # $Id: hotkernel,v 1.2 2016/12/12 16:30:03 christos Exp $ 13 # 14 # USAGE: hotkernel [-hm] 15 # 16 # -h # help 17 # -m # match modules, not functions 18 # eg, 19 # hotkernel # sample kernel functions 20 # hotkernel -m # sample kernel modules 21 # 22 # FIELDS: 23 # FUNCTION Function name 24 # MODULE Module name 25 # COUNT Number of samples 26 # PCNT Percentage of total samples 27 # 28 # COPYRIGHT: Copyright (c) 2006 Brendan Gregg. 29 # 30 # CDDL HEADER START 31 # 32 # The contents of this file are subject to the terms of the 33 # Common Development and Distribution License, Version 1.0 only 34 # (the "License"). You may not use this file except in compliance 35 # with the License. 36 # 37 # You can obtain a copy of the license at Docs/cddl1.txt 38 # or http://www.opensolaris.org/os/licensing. 39 # See the License for the specific language governing permissions 40 # and limitations under the License. 41 # 42 # CDDL HEADER END 43 # 44 # Author: Brendan Gregg [Sydney, Australia] 45 # 46 # 29-Jun-2006 Brendan Gregg Created this. 47 # 29-Jun-2006 " " Last update. 48 # 49 50 use strict; 51 use Getopt::Std; 52 53 # 54 # Command Line Arguments 55 # 56 my $args; 57 usage() if defined $ARGV[0] and $ARGV[0] eq "--help"; 58 getopts('hm') or usage(); 59 usage() if defined $main::opt_h and $main::opt_h; 60 my $mods = defined $main::opt_m and $main::opt_m ? 1 : 0; 61 62 # 63 # Cleanup on signals 64 # 65 $SIG{INT} = \&cleanupsig; # Ctrl-C 66 $SIG{QUIT} = \&cleanupsig; # Ctrl-\ 67 $SIG{TERM} = \&cleanupsig; # TERM 68 69 # 70 # Declare DTrace script 71 # 72 my $dtrace = <<END; 73 /usr/sbin/dtrace -n ' 74 #pragma D option quiet 75 profile:::profile-1001hz 76 /arg0/ 77 { 78 \@pc[arg0] = count(); 79 } 80 dtrace:::END 81 { 82 printa("%a %\@d\\n", \@pc); 83 } 84 ' 85 END 86 87 # 88 # Run DTrace, process output 89 # 90 my %Count; 91 my $total; 92 open DTRACE, "$dtrace |" or die "ERROR1: Can't run dtrace (perms?): $!\n"; 93 print "Sampling... Hit Ctrl-C to end.\n"; 94 while (my $line = <DTRACE>) { 95 next if $line =~ /^\s*$/; 96 my ($addr, $count) = split ' ', $line; 97 my ($name, $offset) = split /\+/, $addr; 98 next if $name eq "0x0"; 99 $name =~ s/\`.*// if $mods; 100 $Count{$name} += $count; 101 $total += $count; 102 } 103 close DTRACE; 104 105 # 106 # Print final report 107 # 108 printf "\n%-52s %8s %6s\n", $mods ? "MODULE" : "FUNCTION", "COUNT", "PCNT"; 109 foreach my $name (sort { $Count{$a} <=> $Count{$b} } keys %Count) { 110 printf "%-52s %8d %5.1f%%\n", $name, $Count{$name}, 111 100 * $Count{$name} / ($total ? $total : 1); 112 } 113 114 # 115 # Subroutines 116 # 117 sub cleanupsig { 118 } 119 sub usage { 120 print STDERR "USAGE: hotkernel [-hm]\n"; 121 print STDERR " eg,\n"; 122 print STDERR " hotkernel # sample kernel functions\n"; 123 print STDERR " hotkernel -m # sample kernel modules\n"; 124 exit 1; 125 } 126