tools/rb/find-comptr-leakers.pl

changeset 0
6474c204b198
     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 +

mercurial