tools/trace-malloc/uncategorized.pl

branch
TOR_BUG_9701
changeset 10
ac0c01689b40
equal deleted inserted replaced
-1:000000000000 0:3941987d783f
1 #!/usr/bin/perl -w
2 #
3 # This Source Code Form is subject to the terms of the Mozilla Public
4 # License, v. 2.0. If a copy of the MPL was not distributed with this
5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7 # This tool is used to construct the ``type inference'' file. It
8 # prints the total number of bytes that are attributed to a type that
9 # cannot be inferred, grouped by stack trace; e.g.,
10 #
11 # (100) PR_Malloc
12 # (50) foo
13 # (50) foo2::foo2
14 # (25) bar
15 # (25) baz
16 # (50) __builtin_new
17 # (50) foo2::foo2
18 #
19 #
20 # Which indicates that 100 bytes were allocated by uninferrable
21 # classes via PR_Malloc(). Of that 100 bytes, 50 were allocated from
22 # calls by foo(), 25 from calls by bar(), and 25 from calls by baz().
23 # 50 bytes were allocated by __builtin_new from foo2's ctor.
24 #
25 #
26 # From this, we might be able to infer the type of the object that was
27 # created by examining the PR_Malloc() usage in foo() and the
28 # ::operator new() usage in foo2(), and could add new type inference
29 # rules; e.g.,
30 #
31 # <unclassified-string>
32 # foo
33 # foo2
34 #
35 # # Attribute ::operator new() usage in foo2's ctor to foo2
36 # <foo2>
37 # __builtin_new
38 # foo2::foo2
39
40 use 5.004;
41 use strict;
42 use Getopt::Long;
43
44 # So we can find TraceMalloc.pm
45 use FindBin;
46 use lib "$FindBin::Bin";
47
48 use TraceMalloc;
49
50 # Collect program options
51 $::opt_help = 0;
52 $::opt_depth = 10;
53 $::opt_types = "${FindBin::Bin}/types.dat";
54 GetOptions("help", "depth=n", "types=s");
55
56 if ($::opt_help) {
57 die "usage: uncategorized.pl [options] <dumpfile>
58 --help Display this message
59 --depth=<n> Display at most <n> stack frames
60 --types=<file> Read type heuristics from <file>";
61 }
62
63 # Initialize type inference juju from the type file specified by
64 # ``--types''.
65 TraceMalloc::init_type_inference($::opt_types);
66
67 # Read the objects from the dump file. For each object, remember up to
68 # ``--depth'' stack frames (from the top). Thread together common
69 # stack prefixes, accumulating the number of bytes attributed to the
70 # prefix.
71
72 # This'll hold the inverted stacks
73 $::Stacks = { '#bytes#' => 0 };
74
75 sub collect_stacks($) {
76 my ($object) = @_;
77 my $stack = $object->{'stack'};
78
79 return unless ($object->{'type'} eq 'void*') && (TraceMalloc::infer_type($stack) eq 'void*');
80
81 my $count = 0;
82 my $link = \%::Stacks;
83 FRAME: foreach my $frame (@$stack) {
84 last FRAME unless $count++ < $::opt_depth;
85
86 $link->{'#bytes#'} += $object->{'size'};
87 $link->{$frame} = { '#bytes#' => 0 } unless $link->{$frame};
88 $link = $link->{$frame};
89 }
90 }
91
92 TraceMalloc::read(\&collect_stacks);
93
94 # Do a depth-first walk of the inverted stack tree.
95
96 sub walk($$) {
97 my ($links, $indent) = @_;
98
99 my @keys;
100 KEY: foreach my $key (keys %$links) {
101 next KEY if $key eq '#bytes#';
102 $keys[$#keys + 1] = $key;
103 }
104
105 foreach my $key (sort { $links->{$b}->{'#bytes#'} <=> $links->{$a}->{'#bytes#'} } @keys) {
106 for (my $i = 0; $i < $indent; ++$i) {
107 print " ";
108 }
109
110 print "($links->{$key}->{'#bytes#'}) $key\n";
111
112 walk($links->{$key}, $indent + 1);
113 }
114 }
115
116 walk(\%::Stacks, 0);
117

mercurial