Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

new stack folders

  • Loading branch information...
commit 8b171a6265c7424aed7425d3b0921dd2af6c5f70 1 parent 213de61
Brendan Gregg authored
Showing with 187 additions and 3 deletions.
  1. +13 −3 README
  2. +90 −0 stackcollapse-perf.pl
  3. +84 −0 stackcollapse-stap.pl
View
16 README
@@ -1,6 +1,8 @@
-FlameGraphs visualize hot-CPU code-paths.
+Flame Graphs visualize hot-CPU code-paths.
-These can be created in 3 steps:
+See: http://dtrace.org/blogs/brendan/2011/12/16/flame-graphs/
+
+These can be created in three steps:
1. Capture stacks
2. Fold stacks
@@ -9,6 +11,8 @@ These can be created in 3 steps:
1. Capture stacks
+Stack samples can be captured using DTrace, perf_events or SystemTap.
+
Using DTrace to capture 60 seconds of kernel stacks at 997 Hertz:
# dtrace -x stackframes=100 -n 'profile-997 /arg0/ { @[stack()] = count(); } tick-60s { exit(0); }' -o out.kern_stacks
@@ -22,7 +26,13 @@ You can include "arg1" in the predicate if you just want to study user-level CPU
2. Fold stacks
-stackcollapse.pl is provided, which currently handles DTrace output. Eg:
+Use the stackcollapse programs to fold stack samples into single lines. The programs provided are:
+
+- stackcollapse.pl: for DTrace stacks
+- stackcollapse-perf.pl: for perf_events "perf script" output
+- stackcollapse-stap.pl: for SystemTap stacks
+
+Usage example:
$ ./stackcollapse.pl out.kern_stacks > out.kern_folded
View
90 stackcollapse-perf.pl
@@ -0,0 +1,90 @@
+#!/usr/bin/perl -w
+#
+# stackcolllapse-perf.pl collapse perf samples into single lines.
+#
+# Parses a list of multiline stacks generated by "perf script", and
+# outputs a comma separated stack followed by a space and a count.
+# If memory addresses (+0xd) are present, they are stripped, and resulting
+# identical stacks are colased with their counts summed.
+#
+# USAGE: ./stackcollapse-perf.pl infile > outfile
+#
+# Example input:
+#
+# swapper 0 [000] 158665.570607: cpu-clock:
+# ffffffff8103ce3b native_safe_halt ([kernel.kallsyms])
+# ffffffff8101c6a3 default_idle ([kernel.kallsyms])
+# ffffffff81013236 cpu_idle ([kernel.kallsyms])
+# ffffffff815bf03e rest_init ([kernel.kallsyms])
+# ffffffff81aebbfe start_kernel ([kernel.kallsyms].init.text)
+# [...]
+#
+# Example output:
+#
+# start_kernel,rest_init,cpu_idle,default_idle,native_safe_halt 1
+#
+# Input may be created and processed using:
+#
+# perf record -a -g -F 997 sleep 60
+# perf script | ./stackcollapse-perf.pl > out.stacks-folded
+#
+# Copyright 2012 Joyent, Inc. All rights reserved.
+# Copyright 2012 Brendan Gregg. All rights reserved.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# 02-Mar-2012 Brendan Gregg Created this.
+
+use strict;
+
+my %collapsed;
+
+sub remember_stack {
+ my ($stack, $count) = @_;
+ $collapsed{$stack} += $count;
+}
+
+my @stack;
+
+foreach (<>) {
+ next if m/^#/;
+ chomp;
+
+ if (m/^$/) {
+ remember_stack(join(",", @stack), 1) if @stack;
+ undef @stack;
+ next;
+ }
+
+ # Note the details skipped below, and customize as desired
+
+ next if m/:.*:/; # skip summary lines
+
+ if (/^\s*\w+ (\w+) (\S+)/) {
+ my ($func, $mod) = ($1, $2);
+ next if $func =~ /\(/; # skip process names
+ next unless $mod =~ /kernel/; # skip non-kernel
+ unshift @stack, $func;
+ }
+}
+
+foreach my $k (sort { $a cmp $b } keys %collapsed) {
+ printf "$k $collapsed{$k}\n";
+}
View
84 stackcollapse-stap.pl
@@ -0,0 +1,84 @@
+#!/usr/bin/perl -w
+#
+# stackcolllapse-stap.pl collapse multiline SystemTap stacks
+# into single lines.
+#
+# Parses a multiline stack followed by a number on a separate line, and
+# outputs a comma separated stack followed by a space and the number.
+# If memory addresses (+0xd) are present, they are stripped, and resulting
+# identical stacks are colased with their counts summed.
+#
+# USAGE: ./stackcollapse.pl infile > outfile
+#
+# Example input:
+#
+# 0xffffffff8103ce3b : native_safe_halt+0xb/0x10 [kernel]
+# 0xffffffff8101c6a3 : default_idle+0x53/0x1d0 [kernel]
+# 0xffffffff81013236 : cpu_idle+0xd6/0x120 [kernel]
+# 0xffffffff815bf03e : rest_init+0x72/0x74 [kernel]
+# 0xffffffff81aebbfe : start_kernel+0x3ba/0x3c5 [kernel]
+# 2404
+#
+# Example output:
+#
+# start_kernel,rest_init,cpu_idle,default_idle,native_safe_halt 2404
+#
+# Input may contain many stacks as generated from SystemTap.
+#
+# Copyright 2011 Joyent, Inc. All rights reserved.
+# Copyright 2011 Brendan Gregg. All rights reserved.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# 16-Feb-2012 Brendan Gregg Created this.
+
+use strict;
+
+my %collapsed;
+
+sub remember_stack {
+ my ($stack, $count) = @_;
+ $collapsed{$stack} += $count;
+}
+
+my @stack;
+
+foreach (<>) {
+ chomp;
+
+ if (m/^\s*(\d+)+$/) {
+ remember_stack(join(",", @stack), $1);
+ @stack = ();
+ next;
+ }
+
+ next if (m/^\s*$/);
+
+ my $frame = $_;
+ $frame =~ s/^\s*//;
+ $frame =~ s/\+.*$//;
+ $frame =~ s/.* : //;
+ $frame = "-" if $frame eq "";
+ unshift @stack, $frame;
+}
+
+foreach my $k (sort { $a cmp $b } keys %collapsed) {
+ printf "$k $collapsed{$k}\n";
+}
Please sign in to comment.
Something went wrong with that request. Please try again.