A relay trace indenting tool, take 2

Duane Clark dclark at akamail.com
Mon Mar 3 13:08:38 CST 2003


My lack of experience with perl is probably showing (I had to consult a 
manual to determine the format of "elsif"). Anyway, I did not need to 
put the "Ret window proc" test in a separate elsif, so combining those 
is the only difference between this and the previous version.

Changelog:
	A tool for indenting calls in relay traces.

-------------- next part --------------
--- /dev/null	Thu Apr 11 07:25:15 2002
+++ tools/indent-relay	Mon Mar  3 11:00:20 2003
@@ -0,0 +1,153 @@
+#!/usr/bin/perl -w
+# -----------------------------------------------------------------------------
+#
+# indent-relay
+#
+# This program will indent the calls of a relay trace. It is a modification
+# of the program examine-relay, which has these copyrights:
+#
+# Copyright 1997-1998 Morten Welinder (terra at diku.dk)
+#           2001      Eric Pouech
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+# -----------------------------------------------------------------------------
+
+use strict;
+
+my $srcfile = $ARGV[0];
+my %tid_callstack = ();
+my $newlineerror = 0;
+my $indentp = 1;
+my $lasttid = 0;
+
+open (IN, "<$srcfile") || die "Cannot open $srcfile for reading: $!\n";
+LINE:
+while (<IN>) {
+
+
+    if (/^([0-9a-f]+):Call ([A-Za-z0-9]+\.[A-Za-z0-9_]+)\((.*\)) .*/) {
+	my $tid = $1;
+	my $func = $2;
+	if ($lasttid ne $tid) {
+	    print "******** thread change\n"
+	}
+	$lasttid = $tid;
+
+#	print "have call func=$func $_";
+	print ($indentp ? (' ' x 2 x (1 + $#{$tid_callstack{$tid}})) : '');
+	print "$_";
+	if (/ ret=(........)$/ ||
+	    / ret=(....:....) (ds=....)$/ ||
+	    / ret=(........) fs=....$/) {
+	    my $retaddr = $1;
+	    my $segreg = $2;
+
+	    $segreg = "none" unless defined $segreg;
+
+	    push @{$tid_callstack{$tid}}, [$func, $retaddr, $segreg];
+	    next;
+	} else {
+	    # Assume a line got cut by a line feed in a string.
+	    $_ .= scalar (<IN>);
+	    if (!$newlineerror) {
+		print "Err[$tid] string probably cut by newline at line $. .\n";
+		$newlineerror = 1;
+	    }
+	    print "[$_]";
+	    redo;
+	}
+    }
+
+    elsif (/^([0-9a-f]+):Call (window proc) ([0-9a-fx]+) .*/) {
+	my $tid = $1;
+	my $func = $2;
+	my $retaddr = $3;
+	my $segreg = "none";
+	if ($lasttid ne $tid) {
+	    print "******** thread change\n"
+	}
+	$lasttid = $tid;
+
+	print ($indentp ? (' ' x 2 x (1 + $#{$tid_callstack{$tid}})) : '');
+	print "$_";
+	push @{$tid_callstack{$tid}}, [$func, $retaddr, $segreg];
+    }
+
+    elsif (/^([0-9a-f]+):Ret  ([A-Za-z0-9]+\.[A-Za-z0-9_]+)\(.*\) .* ret=(........)$/ ||
+	/^([0-9a-f]+):Ret  ([A-Za-z0-9]+\.[A-Za-z0-9_]+)\(.*\) .* ret=(....:....) (ds=....)$/ ||
+	/^([0-9a-f]+):Ret  ([A-Za-z0-9]+\.[A-Za-z0-9_]+)\(.*\) .* ret=(........) fs=....$/ ||
+        /^([0-9a-f]+):RET  ([A-Za-z0-9]+\.[A-Za-z0-9_]+: [A-Za-z0-9]+)\(.*\) .* ret=(........)$/ ||
+        /^([0-9a-f]+):Ret  (window proc) ([0-9a-fx]+) .*/) {
+	my $tid = $1;
+	my $func = $2;
+	my $retaddr = $3;
+	my $segreg = $4;
+	my ($topfunc,$topaddr,$topseg);
+	if ($lasttid ne $tid) {
+	    print "******** thread change\n"
+	}
+	$lasttid = $tid;
+
+#	print "have ret func=$func <$_>\n";
+	if (!defined($tid_callstack{$tid}))
+	{
+	    print "Err[$tid]: unknown tid\n";
+	    next;
+	}
+
+	$segreg = "none" unless defined $segreg;
+
+      POP:
+	while (1) {
+	    if ($#{$tid_callstack{$tid}} == -1) {
+		print "Err[$tid]: Return from $func to $retaddr with empty stack.\n";
+		next LINE;
+	    }
+
+	    ($topfunc,$topaddr,$topseg) = @{pop @{$tid_callstack{$tid}}};
+
+	    if ($topfunc ne $func) {
+		print "Err[$tid]: Return from $topfunc, but call from $func.\n";
+		next POP;
+	    }
+	    last POP;
+	}
+
+	my $addrok = ($topaddr eq $retaddr);
+	my $segok = ($topseg eq $segreg);
+	if ($addrok && $segok) {
+	    print ($indentp ? (' ' x 2 x (1 + $#{$tid_callstack{$tid}})) : '');
+	    print "$_";
+	} else {
+	    print "Err[$tid]: Return from $func is to $retaddr, not $topaddr.\n"
+		if !$addrok;
+	    print "Err[$tid]: Return from $func with segreg $segreg, not $topseg.\n"
+		if !$segok;
+	}
+    }
+    
+    else {
+	print "$_";
+    }
+}
+
+foreach my $tid (keys %tid_callstack) {
+    while ($#{$tid_callstack{$tid}} != -1) {
+	my ($topfunc,$topaddr,$topseg) = @{pop @{$tid_callstack{$tid}}};
+	print "Err[$tid]: leftover call to $topfunc from $topaddr.\n";
+    }
+}
+
+close (IN);


More information about the wine-patches mailing list