1235368Sgnn#!/usr/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 65 2007-10-04 11:09:40Z brendan $ 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 50use strict; 51use Getopt::Std; 52 53# 54# Command Line Arguments 55# 56my $args; 57usage() if defined $ARGV[0] and $ARGV[0] eq "--help"; 58getopts('hm') or usage(); 59usage() if defined $main::opt_h and $main::opt_h; 60my $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# 72my $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' 85END 86 87# 88# Run DTrace, process output 89# 90my %Count; 91my $total; 92open DTRACE, "$dtrace |" or die "ERROR1: Can't run dtrace (perms?): $!\n"; 93print "Sampling... Hit Ctrl-C to end.\n"; 94while (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} 103close DTRACE; 104 105# 106# Print final report 107# 108printf "\n%-52s %8s %6s\n", $mods ? "MODULE" : "FUNCTION", "COUNT", "PCNT"; 109foreach 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# 117sub cleanupsig { 118} 119sub 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