1235368Sgnn#!/usr/bin/perl -w 2235368Sgnn# 3235368Sgnn# hotkernel - sample on-CPU kernel-level functions and modules. 4235368Sgnn# Written using Perl and DTrace (Solaris 10 03/05) 5235368Sgnn# 6235368Sgnn# This samples the on-CPU function at 1001 Hertz, for a simple yet 7235368Sgnn# effective kernel-level profiling tool for sampling exclusive function time. 8235368Sgnn# The output will identify which function is on the CPU the most - which is 9235368Sgnn# the hottest. See Notes/ALLexclusive_notes.txt for an explanation of 10235368Sgnn# exclusive time. 11235368Sgnn# 12235368Sgnn# $Id: hotkernel 65 2007-10-04 11:09:40Z brendan $ 13235368Sgnn# 14235368Sgnn# USAGE: hotkernel [-hm] 15235368Sgnn# 16235368Sgnn# -h # help 17235368Sgnn# -m # match modules, not functions 18235368Sgnn# eg, 19235368Sgnn# hotkernel # sample kernel functions 20235368Sgnn# hotkernel -m # sample kernel modules 21235368Sgnn# 22235368Sgnn# FIELDS: 23235368Sgnn# FUNCTION Function name 24235368Sgnn# MODULE Module name 25235368Sgnn# COUNT Number of samples 26235368Sgnn# PCNT Percentage of total samples 27235368Sgnn# 28235368Sgnn# COPYRIGHT: Copyright (c) 2006 Brendan Gregg. 29235368Sgnn# 30235368Sgnn# CDDL HEADER START 31235368Sgnn# 32235368Sgnn# The contents of this file are subject to the terms of the 33235368Sgnn# Common Development and Distribution License, Version 1.0 only 34235368Sgnn# (the "License"). You may not use this file except in compliance 35235368Sgnn# with the License. 36235368Sgnn# 37235368Sgnn# You can obtain a copy of the license at Docs/cddl1.txt 38235368Sgnn# or http://www.opensolaris.org/os/licensing. 39235368Sgnn# See the License for the specific language governing permissions 40235368Sgnn# and limitations under the License. 41235368Sgnn# 42235368Sgnn# CDDL HEADER END 43235368Sgnn# 44235368Sgnn# Author: Brendan Gregg [Sydney, Australia] 45235368Sgnn# 46235368Sgnn# 29-Jun-2006 Brendan Gregg Created this. 47235368Sgnn# 29-Jun-2006 " " Last update. 48235368Sgnn# 49235368Sgnn 50235368Sgnnuse strict; 51235368Sgnnuse Getopt::Std; 52235368Sgnn 53235368Sgnn# 54235368Sgnn# Command Line Arguments 55235368Sgnn# 56235368Sgnnmy $args; 57235368Sgnnusage() if defined $ARGV[0] and $ARGV[0] eq "--help"; 58235368Sgnngetopts('hm') or usage(); 59235368Sgnnusage() if defined $main::opt_h and $main::opt_h; 60235368Sgnnmy $mods = defined $main::opt_m and $main::opt_m ? 1 : 0; 61235368Sgnn 62235368Sgnn# 63235368Sgnn# Cleanup on signals 64235368Sgnn# 65235368Sgnn$SIG{INT} = \&cleanupsig; # Ctrl-C 66235368Sgnn$SIG{QUIT} = \&cleanupsig; # Ctrl-\ 67235368Sgnn$SIG{TERM} = \&cleanupsig; # TERM 68235368Sgnn 69235368Sgnn# 70235368Sgnn# Declare DTrace script 71235368Sgnn# 72235368Sgnnmy $dtrace = <<END; 73235368Sgnn/usr/sbin/dtrace -n ' 74235368Sgnn #pragma D option quiet 75235368Sgnn profile:::profile-1001hz 76235368Sgnn /arg0/ 77235368Sgnn { 78235368Sgnn \@pc[arg0] = count(); 79235368Sgnn } 80235368Sgnn dtrace:::END 81235368Sgnn { 82235368Sgnn printa("%a %\@d\\n", \@pc); 83235368Sgnn } 84235368Sgnn' 85235368SgnnEND 86235368Sgnn 87235368Sgnn# 88235368Sgnn# Run DTrace, process output 89235368Sgnn# 90235368Sgnnmy %Count; 91235368Sgnnmy $total; 92235368Sgnnopen DTRACE, "$dtrace |" or die "ERROR1: Can't run dtrace (perms?): $!\n"; 93235368Sgnnprint "Sampling... Hit Ctrl-C to end.\n"; 94235368Sgnnwhile (my $line = <DTRACE>) { 95235368Sgnn next if $line =~ /^\s*$/; 96235368Sgnn my ($addr, $count) = split ' ', $line; 97235368Sgnn my ($name, $offset) = split /\+/, $addr; 98235368Sgnn next if $name eq "0x0"; 99235368Sgnn $name =~ s/\`.*// if $mods; 100235368Sgnn $Count{$name} += $count; 101235368Sgnn $total += $count; 102235368Sgnn} 103235368Sgnnclose DTRACE; 104235368Sgnn 105235368Sgnn# 106235368Sgnn# Print final report 107235368Sgnn# 108235368Sgnnprintf "\n%-52s %8s %6s\n", $mods ? "MODULE" : "FUNCTION", "COUNT", "PCNT"; 109235368Sgnnforeach my $name (sort { $Count{$a} <=> $Count{$b} } keys %Count) { 110235368Sgnn printf "%-52s %8d %5.1f%%\n", $name, $Count{$name}, 111235368Sgnn 100 * $Count{$name} / ($total ? $total : 1); 112235368Sgnn} 113235368Sgnn 114235368Sgnn# 115235368Sgnn# Subroutines 116235368Sgnn# 117235368Sgnnsub cleanupsig { 118235368Sgnn} 119235368Sgnnsub usage { 120235368Sgnn print STDERR "USAGE: hotkernel [-hm]\n"; 121235368Sgnn print STDERR " eg,\n"; 122235368Sgnn print STDERR " hotkernel # sample kernel functions\n"; 123235368Sgnn print STDERR " hotkernel -m # sample kernel modules\n"; 124235368Sgnn exit 1; 125235368Sgnn} 126