-
Notifications
You must be signed in to change notification settings - Fork 11
/
bt-aggregate
executable file
·74 lines (55 loc) · 1.79 KB
/
bt-aggregate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/usr/bin/env perl
# This program is part of Aspersa (http://code.google.com/p/aspersa/)
=pod
=head1 NAME
bt-aggregate - Aggregate and print GDB backtraces.
=head1 SYNOPSIS
gdb -ex "set pagination 0" -ex "thread apply all bt" --batch \
-p $(pidof mysqld) > backtrace.txt
bt-aggregate backtrace.txt
For more compact output, set the AS_COMPACT environment variable.
=head1 OPTIONS
=over
=item -n
Aggregate by only the first N lines of each trace.
=back
=head1 AUTHOR
Baron Schwartz
=cut
use strict;
use warnings FATAL => 'all';
use English qw(-no_match_vars);
# Look for command-line arguments to see if we're supposed to aggregate by only
# the first few lines of each stack trace.
my $n_lines = 0;
if ( @ARGV && $ARGV[0] =~ m/^-\d/ ) {
my $arg = shift @ARGV;
($n_lines) = $arg =~ m/(\d+)/;
}
local $INPUT_RECORD_SEPARATOR = ''; # Paragraph mode
my %traces;
while ( my $chunk = <> ) {
next unless my ( $tid ) = $chunk =~ m/^Thread (\d+)/;
$chunk =~ s/\AThread.*$//m; # Delete first line
$chunk =~ s/#$n_lines\s.*//s if $n_lines; # Delete all but first N lines
$chunk =~ s/(\A\s+)|(\s+\Z)//g; # Trim whitespace
# Grab the signature of the chunk.
my $sig = join(',', $chunk =~ m/(^#\d+.*?)\(/gm);
$traces{$sig}->{count}++;
$traces{$sig}->{sample} ||= $chunk;
push @{$traces{$sig}->{tids}}, $tid;
}
foreach my $sig (
reverse sort { $traces{$a}->{count} <=> $traces{$b}->{count} } keys %traces
) {
my $trace = $traces{$sig}->{sample};
if ( $ENV{AS_COMPACT} ) {
printf "%4d %s\n", $traces{$sig}->{count},
join(', ', map { "$_()" } $trace =~ m/ in (\S+) /g);
}
else {
printf "%4d threads with the following stack trace:\n", $traces{$sig}->{count};
$trace =~ s/^/\t/gm;
print $trace, "\n\n";
}
}