diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2016-04-08 13:06:34 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2016-04-08 13:07:06 +0200 |
commit | fda3547b628274c3d97fbde23cd1913346bde09e (patch) | |
tree | 2c6822da15b02bed0dfdca2983fc69d82229d130 | |
parent | 93931c1c445696c1e8825c6075df42865c105c54 (diff) | |
download | NetworkManager-lr/i-hate-everything.tar.gz |
contrib: heap usage analysis toolinglr/i-hate-everything
-rw-r--r-- | contrib/memory/sad.pl | 65 | ||||
-rw-r--r-- | contrib/memory/useless.stp | 37 |
2 files changed, 102 insertions, 0 deletions
diff --git a/contrib/memory/sad.pl b/contrib/memory/sad.pl new file mode 100644 index 0000000000..1e772baf4e --- /dev/null +++ b/contrib/memory/sad.pl @@ -0,0 +1,65 @@ +#!/usr/bin/env perl + +# Summarize the malloc/free trace from useless.stp + +my %allocs; +our %tbcache; + +sub free +{ + my $addr = shift; + return unless exists $allocs{$addr}; + delete ${$allocs{$addr}->{tb}}->{allocs}{$addr}; + delete $allocs{$addr}; +} + +sub malloc +{ + my $size = shift; + my $addr = shift; + + $allocs{$addr} = { addr => $addr, size => $size }; + return \$allocs{$addr} +} + +sub tb +{ + my $tb = shift; + my $addr = shift; + our $tbid; + + $tbcache{$tb} = { tb => $tb, tbid => $tbid++, allocs => {} } unless exists $tbcache{$tb}; + $tb = \$tbcache{$tb}; + $$tb->{allocs}->{$$addr->{addr}} = $addr; + $$addr->{tb} = $tb; +} + +my $tb = ''; +my $addr; +while (<STDIN>) { + if (/^ 0x.* : .*/) { + $tb .= $_; + next; + } else { + tb ($tb, $addr); + $tb = ''; + } + + if (/^free\((.*)\)$/) { + free(hex $1); + } elsif (/^malloc\((.*)\) = (.*)/) { + $addr = malloc($1, hex $2); + } +} + +print "=== Leftover allocations by count ===\n"; +printf "Count: %d, Size: %d\n%s\n", scalar keys %{$_->{allocs}}, ${[values %{$_->{allocs}}]->[0]}->{size}, $_->{tb} + foreach sort { scalar keys %{$b->{allocs}} <=> scalar keys %{$a->{allocs}} } + grep { %{$_->{allocs}} } %tbcache; + + +print "\n=== Leftover allocations by address with sizes and count ===\n"; +for $addr (sort keys %allocs) { + $tb = $allocs{$addr}->{tb}; + printf "0x%x: %20d %8d %8d\n", $addr, $allocs{$addr}->{size}, $$tb->{tbid}, scalar keys %{$$tb->{allocs}}; +} diff --git a/contrib/memory/useless.stp b/contrib/memory/useless.stp new file mode 100644 index 0000000000..a3507780ca --- /dev/null +++ b/contrib/memory/useless.stp @@ -0,0 +1,37 @@ + +/* + Log all allocations and frees: + + stap -g --suppress-time-limits --ldd -vv meh.stp \ + -d /usr/sbin/NetworkManager --ldd -x `pidof NetworkManager` \ + $(cat /proc/`pidof NetworkManager`/maps |awk '/\.so/ {print "-d "$NF}' |sort |uniq) +*/ + +probe begin +{ + if (target() == 0) error ("please specify target process with -c / -x") +} + +probe process("/lib*/libc.so.6").function("sbrk") +{ + printf ("sbrk %s\n", $$parms); +} + +probe process("/lib*/libc.so.6").function("realloc").return +{ + printf ("%s\n", $$parms); +} + +probe process("/lib*/libc.so.6").function("malloc").return +{ + if ($bytes > 0) { + printf ("malloc(%d) = %x\n", $bytes, $return); + print_ubacktrace (); + } +} + +probe process("/lib*/libc.so.6").function("free") +{ + if ($mem > 0) + printf ("free(%x)\n", $mem); +} |