2 # -----------------------------------------------------------------------------
6 # This program will inspect a log file with relay information and tell you
7 # whether calls and returns match. If not, this suggests that the parameter
8 # list might be incorrect. (It could be something else also.)
10 # This program now accepts a second command line parameter, which will enable
11 # a "full" listing format; otherwise a trimmed down simplified listing is
12 # generated. It does not matter what the second command line parameter is;
13 # anything will enable the full listing.
15 # Copyright 1997-1998 Morten Welinder (terra@diku.dk)
18 # This library is free software; you can redistribute it and/or
19 # modify it under the terms of the GNU Lesser General Public
20 # License as published by the Free Software Foundation; either
21 # version 2.1 of the License, or (at your option) any later version.
23 # This library is distributed in the hope that it will be useful,
24 # but WITHOUT ANY WARRANTY; without even the implied warranty of
25 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 # Lesser General Public License for more details.
28 # You should have received a copy of the GNU Lesser General Public
29 # License along with this library; if not, write to the Free Software
30 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 # -----------------------------------------------------------------------------
35 my $srcfile = $ARGV[0];
36 my $fullformat = $ARGV[1];
37 my %tid_callstack = ();
42 open (IN, "<$srcfile") || die "Cannot open $srcfile for reading: $!\n";
47 if (/^([0-9a-f]+):Call ([A-Za-z0-9]+\.[A-Za-z0-9_.]+)\((.*\)) .*/) {
50 if (defined $fullformat) {
51 if ($lasttid ne $tid) {
52 print "******** thread change\n"
56 print ($indentp ? (' ' x 2 x (1 + $#{$tid_callstack{$tid}})) : '');
59 # print "have call func=$func $_";
60 if (/ ret=(........)$/ ||
61 / ret=(....:....) (ds=....)$/ ||
62 / ret=(........) fs=....$/) {
66 $segreg = "none" unless defined $segreg;
68 push @{$tid_callstack{$tid}}, [$func, $retaddr, $segreg];
70 } elsif (not eof IN) {
71 # Assume a line got cut by a line feed in a string.
74 print "Err[$tid] string probably cut by newline at line $. .\n";
82 elsif (/^([0-9a-f]+):Call (window proc) ([0-9a-fx]+) .*/) {
87 if (defined $fullformat) {
88 if ($lasttid ne $tid) {
89 print "******** thread change\n"
92 print ($indentp ? (' ' x 2 x (1 + $#{$tid_callstack{$tid}})) : '');
96 push @{$tid_callstack{$tid}}, [$func, $retaddr, $segreg];
99 elsif (/^([0-9a-f]+):Ret ([A-Za-z0-9]+\.[A-Za-z0-9_.]+)\(.*\) .* ret=(........)$/ ||
100 /^([0-9a-f]+):Ret ([A-Za-z0-9]+\.[A-Za-z0-9_.]+)\(.*\) .* ret=(....:....) (ds=....)$/ ||
101 /^([0-9a-f]+):Ret ([A-Za-z0-9]+\.[A-Za-z0-9_.]+)\(.*\) .* ret=(........) fs=....$/ ||
102 /^([0-9a-f]+):RET ([A-Za-z0-9]+\.[A-Za-z0-9_.]+: [A-Za-z0-9]+)\(.*\) .* ret=(........)$/ ||
103 /^([0-9a-f]+):Ret (window proc) ([0-9a-fx]+) .*/) {
108 my ($topfunc,$topaddr,$topseg);
109 if (defined $fullformat) {
110 if ($lasttid ne $tid) {
111 print "******** thread change\n"
116 # print "have ret func=$func <$_>\n";
117 if (!defined($tid_callstack{$tid}))
119 print "Err[$tid]: unknown tid\n";
123 $segreg = "none" unless defined $segreg;
127 if ($#{$tid_callstack{$tid}} == -1) {
128 print "Err[$tid]: Return from $func to $retaddr with empty stack.\n";
132 ($topfunc,$topaddr,$topseg) = @{pop @{$tid_callstack{$tid}}};
134 if ($topfunc ne $func) {
135 print "Err[$tid]: Return from $topfunc, but call from $func.\n";
141 my $addrok = ($topaddr eq $retaddr);
142 my $segok = ($topseg eq $segreg);
143 if ($addrok && $segok) {
144 if (defined $fullformat) {
145 print ($indentp ? (' ' x 2 x (1 + $#{$tid_callstack{$tid}})) : '');
148 print "Ok [$tid]: ", ($indentp ? (' ' x (1 + $#{$tid_callstack{$tid}})) : '');
149 print "$func from $retaddr with $segreg.\n";
152 print "Err[$tid]: Return from $func is to $retaddr, not $topaddr.\n"
154 print "Err[$tid]: Return from $func with segreg $segreg, not $topseg.\n"
164 foreach my $tid (keys %tid_callstack) {
165 while ($#{$tid_callstack{$tid}} != -1) {
166 my ($topfunc,$topaddr,$topseg) = @{pop @{$tid_callstack{$tid}}};
167 print "Err[$tid]: leftover call to $topfunc from $topaddr.\n";