difffolded.pl 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #!/usr/bin/perl -w
  2. #
  3. # difffolded.pl diff two folded stack files. Use this for generating
  4. # flame graph differentials.
  5. #
  6. # USAGE: ./difffolded.pl [-hns] folded1 folded2 | ./flamegraph.pl > diff2.svg
  7. #
  8. # Options are described in the usage message (-h).
  9. #
  10. # The flamegraph will be colored based on higher samples (red) and smaller
  11. # samples (blue). The frame widths will be based on the 2nd folded file.
  12. # This might be confusing if stack frames disappear entirely; it will make
  13. # the most sense to ALSO create a differential based on the 1st file widths,
  14. # while switching the hues; eg:
  15. #
  16. # ./difffolded.pl folded2 folded1 | ./flamegraph.pl --negate > diff1.svg
  17. #
  18. # Here's what they mean when comparing a before and after profile:
  19. #
  20. # diff1.svg: widths show the before profile, colored by what WILL happen
  21. # diff2.svg: widths show the after profile, colored by what DID happen
  22. #
  23. # INPUT: See stackcollapse* programs.
  24. #
  25. # OUTPUT: The full list of stacks, with two columns, one from each file.
  26. # If a stack wasn't present in a file, the column value is zero.
  27. #
  28. # folded_stack_trace count_from_folded1 count_from_folded2
  29. #
  30. # eg:
  31. #
  32. # funca;funcb;funcc 31 33
  33. # ...
  34. #
  35. # COPYRIGHT: Copyright (c) 2014 Brendan Gregg.
  36. #
  37. # This program is free software; you can redistribute it and/or
  38. # modify it under the terms of the GNU General Public License
  39. # as published by the Free Software Foundation; either version 2
  40. # of the License, or (at your option) any later version.
  41. #
  42. # This program is distributed in the hope that it will be useful,
  43. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  44. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  45. # GNU General Public License for more details.
  46. #
  47. # You should have received a copy of the GNU General Public License
  48. # along with this program; if not, write to the Free Software Foundation,
  49. # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  50. #
  51. # (http://www.gnu.org/copyleft/gpl.html)
  52. #
  53. # 28-Oct-2014 Brendan Gregg Created this.
  54. use strict;
  55. use Getopt::Std;
  56. # defaults
  57. my $normalize = 0; # make sample counts equal
  58. my $striphex = 0; # strip hex numbers
  59. sub usage {
  60. print STDERR <<USAGE_END;
  61. USAGE: $0 [-hns] folded1 folded2 | flamegraph.pl > diff2.svg
  62. -h # help message
  63. -n # normalize sample counts
  64. -s # strip hex numbers (addresses)
  65. See stackcollapse scripts for generating folded files.
  66. Also consider flipping the files and hues to highlight reduced paths:
  67. $0 folded2 folded1 | ./flamegraph.pl --negate > diff1.svg
  68. USAGE_END
  69. exit 2;
  70. }
  71. usage() if @ARGV < 2;
  72. our($opt_h, $opt_n, $opt_s);
  73. getopts('ns') or usage();
  74. usage() if $opt_h;
  75. $normalize = 1 if defined $opt_n;
  76. $striphex = 1 if defined $opt_s;
  77. my ($total1, $total2) = (0, 0);
  78. my %Folded;
  79. my $file1 = $ARGV[0];
  80. my $file2 = $ARGV[1];
  81. open FILE, $file1 or die "ERROR: Can't read $file1\n";
  82. while (<FILE>) {
  83. chomp;
  84. my ($stack, $count) = (/^(.*)\s+?(\d+(?:\.\d*)?)$/);
  85. $stack =~ s/0x[0-9a-fA-F]+/0x.../g if $striphex;
  86. $Folded{$stack}{1} += $count;
  87. $total1 += $count;
  88. }
  89. close FILE;
  90. open FILE, $file2 or die "ERROR: Can't read $file2\n";
  91. while (<FILE>) {
  92. chomp;
  93. my ($stack, $count) = (/^(.*)\s+?(\d+(?:\.\d*)?)$/);
  94. $stack =~ s/0x[0-9a-fA-F]+/0x.../g if $striphex;
  95. $Folded{$stack}{2} += $count;
  96. $total2 += $count;
  97. }
  98. close FILE;
  99. foreach my $stack (keys %Folded) {
  100. $Folded{$stack}{1} = 0 unless defined $Folded{$stack}{1};
  101. $Folded{$stack}{2} = 0 unless defined $Folded{$stack}{2};
  102. if ($normalize && $total1 != $total2) {
  103. $Folded{$stack}{1} = int($Folded{$stack}{1} * $total2 / $total1);
  104. }
  105. print "$stack $Folded{$stack}{1} $Folded{$stack}{2}\n";
  106. }