thcstackcollapse.pl 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/perl -w
  2. #
  3. # thcstackcollapse.pl collapse thread hot/cold multiline stacks into
  4. # single lines.
  5. #
  6. # EXPERIMENTAL: This is a work in progress, and may not work properly.
  7. #
  8. # Parses a multiline stack followed by thread ID, PID, TID, name, oncpu status,
  9. # and ms on a separate line (see example below) and outputs a comma separated
  10. # stack followed by a space and the numbers. If memory addresses (+0xd) are
  11. # present, they are stripped, and resulting identical stacks are colased with
  12. # their counts summed.
  13. #
  14. # USAGE: ./thcstackcollapse.pl infile > outfile
  15. #
  16. # Example input:
  17. #
  18. # mysqld`_Z10do_commandP3THD+0xd4
  19. # mysqld`handle_one_connection+0x1a6
  20. # libc.so.1`_thrp_setup+0x8d
  21. # libc.so.1`_lwp_start
  22. # thread:0x78372480 pid:826 tid:3 name:mysqld oncpu:1 ms:2664
  23. #
  24. # Example output:
  25. #
  26. # libc.so.1`_lwp_start,libc.so.1`_thrp_setup,mysqld`handle_one_connection,mysqld`_Z10do_commandP3THD 0x78372480 826 3 mysqld 1 2664
  27. #
  28. # Input may contain many stacks, and can be generated using DTrace. The
  29. # first few lines of input are skipped (see $headerlines).
  30. #
  31. # Copyright 2013 Joyent, Inc. All rights reserved.
  32. # Copyright 2013 Brendan Gregg. All rights reserved.
  33. #
  34. # CDDL HEADER START
  35. #
  36. # The contents of this file are subject to the terms of the
  37. # Common Development and Distribution License (the "License").
  38. # You may not use this file except in compliance with the License.
  39. #
  40. # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  41. # or http://www.opensolaris.org/os/licensing.
  42. # See the License for the specific language governing permissions
  43. # and limitations under the License.
  44. #
  45. # When distributing Covered Code, include this CDDL HEADER in each
  46. # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  47. # If applicable, add the following below this CDDL HEADER, with the
  48. # fields enclosed by brackets "[]" replaced with your own identifying
  49. # information: Portions Copyright [yyyy] [name of copyright owner]
  50. #
  51. # CDDL HEADER END
  52. #
  53. # 14-Aug-2011 Brendan Gregg Created this.
  54. use strict;
  55. my %collapsed;
  56. my $headerlines = 2;
  57. sub remember_stack {
  58. my ($stack, $thread, $pid, $tid, $name, $oncpu, $count) = @_;
  59. $collapsed{"$stack $thread $pid $tid $name $oncpu"} += $count;
  60. }
  61. my $nr = 0;
  62. my @stack;
  63. foreach (<>) {
  64. next if $nr++ < $headerlines;
  65. chomp;
  66. next if (m/^\s*$/);
  67. if (m/^thread:(\d+) pid:(\d+) tid:(\d+) name:(.*?) oncpu:(\d+) ms:(\d+)$/) {
  68. remember_stack(join(",", @stack), $1, $2, $3, $4, $5, $6) if $6 > 0;
  69. @stack = ();
  70. next;
  71. }
  72. my $frame = $_;
  73. $frame =~ s/^\s*//;
  74. $frame =~ s/\+.*$//;
  75. $frame = "-" if $frame eq "";
  76. unshift @stack, $frame;
  77. }
  78. foreach my $k (sort { $a cmp $b } keys %collapsed) {
  79. print "$k $collapsed{$k}\n";
  80. }