Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1 | #!/usr/bin/perl -w |
| 2 | # ----------------------------------------------------------------------------- |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 3 | # |
| 4 | # Relay-checker. |
| 5 | # |
| 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.) |
| 9 | # |
| 10 | # Copyright 1997-1998 Morten Welinder (terra@diku.dk) |
| 11 | # |
| 12 | # ----------------------------------------------------------------------------- |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 13 | |
| 14 | my $srcfile = $ARGV[0]; |
| 15 | my @callstack = (); |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 16 | my $newlineerror = 0; |
| 17 | my $indentp = 1; |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 18 | |
| 19 | open (IN, "<$srcfile") || die "Cannot open $srcfile for reading: $!\n"; |
| 20 | LINE: |
| 21 | while (<IN>) { |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 22 | if (/^Call ([A-Za-z0-9]+\.\d+): .*\)/) { |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 23 | my $func = $1; |
| 24 | if (/ ret=(........)$/ || |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 25 | / ret=(....:....) (ds=....)$/ || |
| 26 | / ret=(........) (fs=....)$/) { |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 27 | my $retaddr = $1; |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 28 | my $segreg = $2; |
| 29 | |
| 30 | $segreg = "none" unless defined $segreg; |
| 31 | push @callstack, [$func,$retaddr, $segreg]; |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 32 | next; |
| 33 | } else { |
| 34 | # Assume a line got cut by a line feed in a string. |
| 35 | $_ .= scalar (<IN>); |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 36 | if (!$newlineerror) { |
| 37 | print "Error: string probably cut by newline.\n"; |
| 38 | $newlineerror = 1; |
| 39 | } |
| 40 | # print "[$_]"; |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 41 | redo; |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 46 | if (/^Ret ([A-Za-z0-9]+\.\d+): .* ret=(........)$/ || |
| 47 | /^Ret ([A-Za-z0-9]+\.\d+): .* ret=(....:....) (ds=....)$/ || |
| 48 | /^Ret ([A-Za-z0-9]+\.\d+): .* ret=(........) (fs=....)$/) { |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 49 | my $func = $1; |
| 50 | my $retaddr = $2; |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 51 | my $segreg = $3; |
| 52 | my ($topfunc,$topaddr,$topseg); |
| 53 | |
| 54 | $segreg = "none" unless defined $segreg; |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 55 | |
| 56 | POP: |
| 57 | while (1) { |
| 58 | if ($#callstack == -1) { |
| 59 | print "Error: Return from $func to $retaddr with empty stack.\n"; |
| 60 | next LINE; |
| 61 | } |
| 62 | |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 63 | ($topfunc,$topaddr,$topseg) = @{pop @callstack}; |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 64 | |
| 65 | if ($topfunc ne $func) { |
| 66 | print "Error: Return from $topfunc, but call from $func.\n"; |
| 67 | next POP |
| 68 | } |
| 69 | last POP; |
| 70 | } |
| 71 | |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 72 | my $addrok = ($topaddr eq $retaddr); |
| 73 | my $segok = ($topseg eq $segreg); |
| 74 | if ($addrok && $segok) { |
| 75 | print "OK: ", ($indentp ? (' ' x (1 + $#callstack)) : ''); |
| 76 | print "$func from $retaddr with $segreg.\n"; |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 77 | } else { |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 78 | print "Error: Return from $func is to $retaddr, not $topaddr.\n" |
| 79 | if !$addrok; |
| 80 | print "Error: Return from $func with segreg $segreg, not $topseg.\n" |
| 81 | if !$segok; |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 82 | } |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | while ($#callstack != -1) { |
| 87 | my ($topfunc,$topaddr) = @{pop @callstack}; |
| 88 | print "Error: leftover call to $topfunc from $topaddr.\n"; |
| 89 | } |
| 90 | |
| 91 | close (IN); |