tools/trace-malloc/uncategorized.pl

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rwxr-xr-x

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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/.
     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
    40 use 5.004;
    41 use strict;
    42 use Getopt::Long;
    44 # So we can find TraceMalloc.pm
    45 use FindBin;
    46 use lib "$FindBin::Bin";
    48 use TraceMalloc;
    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");
    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 }
    63 # Initialize type inference juju from the type file specified by
    64 # ``--types''.
    65 TraceMalloc::init_type_inference($::opt_types);
    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.
    72 # This'll hold the inverted stacks
    73 $::Stacks = { '#bytes#' => 0 };
    75 sub collect_stacks($) {
    76     my ($object) = @_;
    77     my $stack = $object->{'stack'};
    79     return unless ($object->{'type'} eq 'void*') && (TraceMalloc::infer_type($stack) eq 'void*');
    81     my $count = 0;
    82     my $link = \%::Stacks;
    83   FRAME: foreach my $frame (@$stack) {
    84       last FRAME unless $count++ < $::opt_depth;
    86       $link->{'#bytes#'} += $object->{'size'};
    87       $link->{$frame} = { '#bytes#' => 0 } unless $link->{$frame};
    88       $link = $link->{$frame};
    89   }
    90 }
    92 TraceMalloc::read(\&collect_stacks);
    94 # Do a depth-first walk of the inverted stack tree.
    96 sub walk($$) {
    97     my ($links, $indent) = @_;
    99     my @keys;
   100   KEY: foreach my $key (keys %$links) {
   101       next KEY if $key eq '#bytes#';
   102       $keys[$#keys + 1] = $key;
   103   }
   105     foreach my $key (sort { $links->{$b}->{'#bytes#'} <=> $links->{$a}->{'#bytes#'} } @keys) {
   106         for (my $i = 0; $i < $indent; ++$i) {
   107             print "  ";
   108         }
   110         print "($links->{$key}->{'#bytes#'}) $key\n";
   112         walk($links->{$key}, $indent + 1);
   113     }
   114 }
   116 walk(\%::Stacks, 0);

mercurial