]>
Commit | Line | Data |
---|---|---|
93afd047 MT |
1 | #! /usr/bin/perl |
2 | ||
3 | sub addr2line; | |
4 | ||
5 | $list = shift; | |
6 | $bin = shift; | |
7 | $ofs = shift; | |
8 | ||
9 | die "usage: mci data_file binary\n" unless -f($list); | |
10 | ||
11 | open F, $list; | |
12 | ||
13 | while(<F>) { | |
14 | if(/^;\s*(.+?)\s*$/) { | |
15 | @i = split ' ', $1; | |
16 | $i[0] = sprintf "%-24s", $i[0]; | |
17 | $i[1] = addr2line $i[1]; | |
18 | print "; ", join("\t", @i), "\n"; | |
19 | next | |
20 | } | |
21 | @i = split; | |
22 | ||
23 | die "oops, format error" if @i > 3; | |
24 | ||
25 | if(@i == 1) { | |
26 | if($i[0] =~ /^>(\S+)/) { | |
27 | unshift @funcs, $1; | |
28 | } | |
29 | elsif($i[0] =~ /<(\S+)/) { | |
30 | if($funcs[0] eq $1) { | |
31 | shift @funcs | |
32 | } | |
33 | else { | |
34 | die "oops, strange data (line $.)\n" | |
35 | } | |
36 | } | |
37 | else { | |
38 | die "oops, format error" | |
39 | } | |
40 | } | |
41 | else { | |
42 | $func = $i[0]; | |
43 | $addr = $i[1]; | |
44 | $size = undef; | |
45 | $size = @i == 2 ? undef : $i[2]; | |
46 | ||
47 | if(defined $size) { | |
48 | if(exists $mem{$addr}) { | |
49 | $x = addr2line $func; | |
50 | $y = addr2line ${$mem{$addr}}[1]; | |
51 | print "malloc oops (line $.): mem $addr; old: $y, size ${$mem{$addr}}[0]; new: $x, size $size\n"; | |
52 | } | |
53 | $mem{$addr} = [ $size, $func, @funcs ]; | |
54 | delete $lfree{$addr}; | |
55 | } | |
56 | else { | |
57 | if(!exists $mem{$addr}) { | |
58 | $xx = ""; | |
59 | $first = 1; | |
60 | for $f ($func, @funcs) { | |
61 | $xx .= "<-" unless $first; | |
62 | $first = 0; | |
63 | $xx .= addr2line $f; | |
64 | } | |
65 | print "free oops (line $.): $addr ($xx) [last free: line $lfree{$addr}]\n"; | |
66 | } | |
67 | delete $mem{$addr}; | |
68 | $lfree{$addr} .= " $."; | |
69 | } | |
70 | } | |
71 | } | |
72 | ||
73 | for (sort keys %mem) { | |
74 | $total += oct(${$mem{$_}}[0]); | |
75 | $cnt++; | |
76 | ||
77 | # $x = `addr2line -s -e $bin ${$mem{$_}}[1]`; | |
78 | # chomp $x; | |
79 | # $x = $x =~ /\?{2}/ ? undef : "$x "; | |
80 | $x = addr2line ${$mem{$_}}[1]; | |
81 | ||
82 | print "$_\t${$mem{$_}}[0]\t"; | |
83 | $first = 1; | |
84 | for $f (@{$mem{$_}}[1..$#{$mem{$_}}]) { | |
85 | print "<-" unless $first; | |
86 | $first = 0; | |
87 | print addr2line $f; | |
88 | } | |
89 | print "\n" | |
90 | } | |
91 | ||
92 | printf "total: %u bytes in %u blocks\n", $total, $cnt; | |
93 | ||
94 | ||
95 | sub addr2line | |
96 | { | |
97 | my ($x, $y); | |
98 | ||
99 | return $_[0] unless $bin; | |
100 | ||
101 | $y = sprintf "0x%x", oct($_[0]) + $ofs; | |
102 | ||
103 | return $addr_cache{$y} if exists $addr_cache{$y}; | |
104 | ||
105 | $x = `addr2line -s -e $bin $y`; | |
106 | chomp $x; | |
107 | $x = $x =~ /\?{2}/ ? $_[0] : $x; | |
108 | ||
109 | $addr_cache{$y} = $x; | |
110 | ||
111 | return $x; | |
112 | } | |
113 |