1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/tools/rb/find-comptr-leakers.pl Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,114 @@ 1.4 +#!/usr/bin/perl -w 1.5 +# 1.6 +# This Source Code Form is subject to the terms of the Mozilla Public 1.7 +# License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 +# file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.9 + 1.10 +# Script loosely based on Chris Waterson's find-leakers.pl and make-tree.pl 1.11 + 1.12 +use 5.004; 1.13 +use strict; 1.14 +use Getopt::Long; 1.15 + 1.16 +# GetOption will create $opt_object, so ignore the 1.17 +# warning that gets spit out about those vbls. 1.18 +GetOptions("object=s", "list", "help"); 1.19 + 1.20 +# use $::opt_help twice to eliminate warning... 1.21 +($::opt_help) && ($::opt_help) && die qq{ 1.22 +usage: find-comptr-leakers.pl < logfile 1.23 + --object <obj> Examine only object <obj> 1.24 + --list Only list leaked objects 1.25 + --help This message :-) 1.26 +}; 1.27 + 1.28 +if ($::opt_object) { 1.29 + warn "Examining only object $::opt_object (THIS IS BROKEN)\n"; 1.30 +} else { 1.31 + warn "Examining all objects\n"; 1.32 +} 1.33 + 1.34 +my %allocs = ( ); 1.35 +my %counter; 1.36 +my $id = 0; 1.37 + 1.38 +my $accumulating = 0; 1.39 +my $savedata = 0; 1.40 +my $class; 1.41 +my $obj; 1.42 +my $sno; 1.43 +my $op; 1.44 +my $cnt; 1.45 +my $ptr; 1.46 +my $strace; 1.47 + 1.48 +sub save_data { 1.49 + # save the data 1.50 + if ($op eq 'nsCOMPtrAddRef') { 1.51 + push @{ $allocs{$sno}->{$ptr} }, [ +1, $strace ]; 1.52 + } 1.53 + elsif ($op eq 'nsCOMPtrRelease') { 1.54 + push @{ $allocs{$sno}->{$ptr} }, [ -1, $strace ]; 1.55 + my $sum = 0; 1.56 + my @ptrallocs = @{ $allocs{$sno}->{$ptr} }; 1.57 + foreach my $alloc (@ptrallocs) { 1.58 + $sum += @$alloc[0]; 1.59 + } 1.60 + if ( $sum == 0 ) { 1.61 + delete($allocs{$sno}{$ptr}); 1.62 + } 1.63 + } 1.64 +} 1.65 + 1.66 +LINE: while (<>) { 1.67 + if (/^</) { 1.68 + chop; # avoid \n in $ptr 1.69 + my @fields = split(/ /, $_); 1.70 + 1.71 + ($class, $obj, $sno, $op, $cnt, $ptr) = @fields; 1.72 + 1.73 + $strace = ""; 1.74 + 1.75 + if ($::opt_list) { 1.76 + save_data(); 1.77 + } elsif (!($::opt_object) || ($::opt_object eq $obj)) { 1.78 + $accumulating = 1; 1.79 + } 1.80 + } elsif ( $accumulating == 1 ) { 1.81 + if ( /^$/ ) { 1.82 + # if line is empty 1.83 + $accumulating = 0; 1.84 + save_data(); 1.85 + } else { 1.86 + $strace = $strace . $_; 1.87 + } 1.88 + } 1.89 +} 1.90 +if ( $accumulating == 1) { 1.91 + save_data(); 1.92 +} 1.93 + 1.94 +foreach my $serial (keys(%allocs)) { 1.95 + foreach my $comptr (keys( %{$allocs{$serial}} )) { 1.96 + my $sum = 0; 1.97 + my @ptrallocs = @{ $allocs{$serial}->{$comptr} }; 1.98 + foreach my $alloc (@ptrallocs) { 1.99 + $sum += @$alloc[0]; 1.100 + } 1.101 + print "Object ", $serial, " held by ", $comptr, " is ", $sum, " out of balance.\n"; 1.102 + unless ($::opt_list) { 1.103 + print "\n"; 1.104 + foreach my $alloc (@ptrallocs) { 1.105 + if (@$alloc[0] == +1) { 1.106 + print "Put into nsCOMPtr at:\n"; 1.107 + } elsif (@$alloc[0] == -1) { 1.108 + print "Released from nsCOMPtr at:\n"; 1.109 + } 1.110 + print @$alloc[1]; # the stack trace 1.111 + print "\n"; 1.112 + } 1.113 + print "\n\n"; 1.114 + } 1.115 + } 1.116 +} 1.117 +