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