Change the filtering of helgrind's XML output.
New file helgrind/tests/filter_xml.
Update expected result for tc06_two_races_xml.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12077 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/helgrind/tests/filter_xml b/helgrind/tests/filter_xml
new file mode 100755
index 0000000..282de5c
--- /dev/null
+++ b/helgrind/tests/filter_xml
@@ -0,0 +1,156 @@
+#!/usr/bin/env perl
+
+#---------------------------------------------------------------------
+# Quick and dirty program to filter helgrind's XML output.
+#
+# The script works line-by-line and is generally unaware of XML structure
+# and does not bother with issues of well-formedness.
+#
+# Consists of two parts
+# (1) Global match and replace (see PATTERNS below)
+# (2) Removal of stack frames
+# Stack frames whose associated file name does not match any name in
+# TOOL_FILES or in the list of files given on the command line
+# will be discarded. For a sequence of one or more discarded frames
+# a line <frame>...</frame> will be inserted.
+#
+#---------------------------------------------------------------------
+
+use warnings;
+use strict;
+
+#---------------------------------------------------------------------
+# A list of files specific to the tool at hand. Line numbers in
+# these files will be removed from stack frames matching these files.
+#---------------------------------------------------------------------
+my @tool_files = ( "hg_intercepts.c", "vg_replace_malloc.c" );
+
+# List of patterns and replacement strings.
+# Each pattern must identify a substring which will be replaced.
+my %patterns = (
+ "<pid>(.*)</pid>" => "...",
+ "<ppid>(.*)</ppid>" => "...",
+ "<time>(.*)</time>" => "...",
+ "<obj>(.*)</obj>" => "...",
+ "<dir>(.*)</dir>" => "...",
+ "<exe>(.*)</exe>" => "...",
+ "<tid>(.*)</tid>" => "...",
+ "<unique>(.*)</unique>" => "...",
+ "thread #([0-9]+)" => "x",
+ "0x([0-9a-zA-Z]+)" => "........",
+ "Using Valgrind-([^\\s]*)" => "X.Y.X",
+ "Copyright \\(C\\) ([0-9]{4}-[0-9]{4}).*" => "XXXX-YYYY"
+);
+
+# List of XML sections to be ignored.
+my %ignore_sections = (
+ "<errorcounts>" => "</errorcounts>",
+ "<suppcounts>" => "</suppcounts>"
+);
+
+
+# If FILE matches any of the FILES return 1
+sub file_matches ($$) {
+ my ($file, $files) = @_;
+ my ($string, $qstring);
+
+ foreach $string (@$files) {
+ $qstring = quotemeta($string);
+ return 1 if ($file =~ /$qstring/);
+ }
+
+ return 0;
+}
+
+
+my $frame_buf = "";
+my ($file, $lineno, $in_frame, $keep_frame, $num_discarded, $ignore_line);
+
+$in_frame = $keep_frame = $num_discarded = $ignore_line = 0;
+
+line:
+while (<STDIN>) {
+ my $line = $_;
+ chomp($line);
+
+# Check whether we're ignoring this piece of XML..
+ if ($ignore_line) {
+ foreach my $tag (keys %ignore_sections) {
+ if ($line =~ $ignore_sections{$tag}) {
+ print "$tag...$ignore_sections{$tag}\n";
+ $ignore_line = 0;
+ next line;
+ }
+ }
+ } else {
+ foreach my $tag (keys %ignore_sections) {
+ if ($line =~ $tag) {
+ $ignore_line = 1;
+ }
+ }
+ }
+
+ next if ($ignore_line);
+
+# OK. This line is not to be ignored.
+
+# Massage line by applying PATTERNS.
+ foreach my $key (keys %patterns) {
+ if ($line =~ $key) {
+ $line =~ s/$1/$patterns{$key}/g;
+ }
+ }
+
+# Handle frames
+ if ($in_frame) {
+ if ($line =~ /<\/frame>/) {
+ $frame_buf .= "$line\n";
+# The end of a frame
+ if ($keep_frame) {
+# First: If there were any preceding frames that were discarded
+# print <frame>...</frame>
+ if ($num_discarded) {
+ print " <frame>...</frame>\n";
+ $num_discarded = 0;
+ }
+# Secondly: Write out the frame itself
+ print "$frame_buf";
+ } else {
+# We don't want to write this frame
+ ++$num_discarded;
+ }
+ $in_frame = $keep_frame = 0;
+ $file = "";
+ } elsif ($line =~ /<file>(.*)<\/file>/) {
+ $frame_buf .= "$line\n";
+ $file = $1;
+ if (file_matches($file, \@tool_files) ||
+ file_matches($file, \@ARGV)) {
+ $keep_frame = 1;
+ }
+ } elsif ($line =~ /<line>(.*)<\/line>/) {
+# This code assumes that <file> always precedes <line>
+ $lineno = $1;
+ if (file_matches($file, \@tool_files)) {
+ $line =~ s/$1/.../;
+ }
+ $frame_buf .= "$line\n";
+ } else {
+ $frame_buf .= "$line\n";
+ }
+ } else {
+# not within frame
+ if ($line =~ /<\/stack>/) {
+ print " <frame>...</frame>\n" if ($num_discarded);
+ $num_discarded = 0;
+ }
+ if ($line =~ /<frame>/) {
+ $in_frame = 1;
+ $frame_buf = "$line\n";
+ } else {
+ print "$line\n";
+ }
+ }
+}
+
+exit 0;
diff --git a/helgrind/tests/tc06_two_races_xml.stderr.exp b/helgrind/tests/tc06_two_races_xml.stderr.exp
index 25ee580..0fd5cd4 100644
--- a/helgrind/tests/tc06_two_races_xml.stderr.exp
+++ b/helgrind/tests/tc06_two_races_xml.stderr.exp
@@ -6,10 +6,10 @@
<protocoltool>helgrind</protocoltool>
<preamble>
- <line>...</line>
- <line>...</line>
- <line>...</line>
- <line>...</line>
+ <line>Helgrind, a thread error detector</line>
+ <line>Copyright (C) XXXX-YYYY, and GNU GPL'd, by OpenWorks LLP et al.</line>
+ <line>Using Valgrind-X.Y.X and LibVEX; rerun with -h for copyright info</line>
+ <line>Command: ./tc06_two_races</line>
</preamble>
<pid>...</pid>
@@ -17,9 +17,18 @@
<tool>helgrind</tool>
<args>
- <vargv>...</vargv>
+ <vargv>
+ <exe>...</exe>
+ <arg>--command-line-only=yes</arg>
+ <arg>--memcheck:leak-check=no</arg>
+ <arg>--tool=helgrind</arg>
+ <arg>--read-var-info=yes</arg>
+ <arg>--xml=yes</arg>
+ <arg>--xml-fd=2</arg>
+ <arg>--log-file=/dev/null</arg>
+ </vargv>
<argv>
- <exe>./tc06_two_races</exe>
+ <exe>...</exe>
</argv>
</args>
@@ -36,22 +45,7 @@
<announcethread>
<hthreadid>2</hthreadid>
<stack>
- <frame>
- <ip>0x........</ip>
- <obj>...</obj>
- <fn>clone</fn>
- <dir>...</dir>
- <file>clone.S</file>
- <line>...</line>
- </frame>
- <frame>
- <ip>0x........</ip>
- <obj>...</obj>
- <fn>pthread_create@@GLIBC_2.2.5</fn>
- <dir>...</dir>
- <file>createthread.c</file>
- <line>...</line>
- </frame>
+ <frame>...</frame>
<frame>
<ip>0x........</ip>
<obj>...</obj>
@@ -74,13 +68,13 @@
<fn>main</fn>
<dir>...</dir>
<file>tc06_two_races.c</file>
- <line>...</line>
+ <line>26</line>
</frame>
</stack>
</announcethread>
<error>
- <unique>0x........</unique>
+ <unique>...</unique>
<tid>...</tid>
<kind>Race</kind>
<xwhat>
@@ -94,7 +88,7 @@
<fn>main</fn>
<dir>...</dir>
<file>tc06_two_races.c</file>
- <line>...</line>
+ <line>31</line>
</frame>
</stack>
<xauxwhat>
@@ -108,7 +102,7 @@
<fn>child_fn</fn>
<dir>...</dir>
<file>tc06_two_races.c</file>
- <line>...</line>
+ <line>14</line>
</frame>
<frame>
<ip>0x........</ip>
@@ -118,24 +112,14 @@
<file>hg_intercepts.c</file>
<line>...</line>
</frame>
- <frame>
- <ip>0x........</ip>
- <obj>...</obj>
- <fn>start_thread</fn>
- <dir>...</dir>
- <file>pthread_create.c</file>
- <line>...</line>
- </frame>
- <frame>
- <ip>0x........</ip>
- </frame>
+ <frame>...</frame>
</stack>
<auxwhat>Location 0x........ is 0 bytes inside global var "unprot1"</auxwhat>
- <xauxwhat><text>declared at tc06_two_races.c:9</text> <file>tc06_two_races.c</file> <line>...</line> </xauxwhat>
+ <xauxwhat><text>declared at tc06_two_races.c:9</text> <file>tc06_two_races.c</file> <line>9</line> </xauxwhat>
</error>
<error>
- <unique>0x........</unique>
+ <unique>...</unique>
<tid>...</tid>
<kind>Race</kind>
<xwhat>
@@ -149,7 +133,7 @@
<fn>main</fn>
<dir>...</dir>
<file>tc06_two_races.c</file>
- <line>...</line>
+ <line>31</line>
</frame>
</stack>
<xauxwhat>
@@ -163,7 +147,7 @@
<fn>child_fn</fn>
<dir>...</dir>
<file>tc06_two_races.c</file>
- <line>...</line>
+ <line>14</line>
</frame>
<frame>
<ip>0x........</ip>
@@ -173,24 +157,14 @@
<file>hg_intercepts.c</file>
<line>...</line>
</frame>
- <frame>
- <ip>0x........</ip>
- <obj>...</obj>
- <fn>start_thread</fn>
- <dir>...</dir>
- <file>pthread_create.c</file>
- <line>...</line>
- </frame>
- <frame>
- <ip>0x........</ip>
- </frame>
+ <frame>...</frame>
</stack>
<auxwhat>Location 0x........ is 0 bytes inside global var "unprot1"</auxwhat>
- <xauxwhat><text>declared at tc06_two_races.c:9</text> <file>tc06_two_races.c</file> <line>...</line> </xauxwhat>
+ <xauxwhat><text>declared at tc06_two_races.c:9</text> <file>tc06_two_races.c</file> <line>9</line> </xauxwhat>
</error>
<error>
- <unique>0x........</unique>
+ <unique>...</unique>
<tid>...</tid>
<kind>Race</kind>
<xwhat>
@@ -204,7 +178,7 @@
<fn>main</fn>
<dir>...</dir>
<file>tc06_two_races.c</file>
- <line>...</line>
+ <line>35</line>
</frame>
</stack>
<xauxwhat>
@@ -218,7 +192,7 @@
<fn>child_fn</fn>
<dir>...</dir>
<file>tc06_two_races.c</file>
- <line>...</line>
+ <line>18</line>
</frame>
<frame>
<ip>0x........</ip>
@@ -228,24 +202,14 @@
<file>hg_intercepts.c</file>
<line>...</line>
</frame>
- <frame>
- <ip>0x........</ip>
- <obj>...</obj>
- <fn>start_thread</fn>
- <dir>...</dir>
- <file>pthread_create.c</file>
- <line>...</line>
- </frame>
- <frame>
- <ip>0x........</ip>
- </frame>
+ <frame>...</frame>
</stack>
<auxwhat>Location 0x........ is 0 bytes inside global var "unprot2"</auxwhat>
- <xauxwhat><text>declared at tc06_two_races.c:9</text> <file>tc06_two_races.c</file> <line>...</line> </xauxwhat>
+ <xauxwhat><text>declared at tc06_two_races.c:9</text> <file>tc06_two_races.c</file> <line>9</line> </xauxwhat>
</error>
<error>
- <unique>0x........</unique>
+ <unique>...</unique>
<tid>...</tid>
<kind>Race</kind>
<xwhat>
@@ -259,7 +223,7 @@
<fn>main</fn>
<dir>...</dir>
<file>tc06_two_races.c</file>
- <line>...</line>
+ <line>35</line>
</frame>
</stack>
<xauxwhat>
@@ -273,7 +237,7 @@
<fn>child_fn</fn>
<dir>...</dir>
<file>tc06_two_races.c</file>
- <line>...</line>
+ <line>18</line>
</frame>
<frame>
<ip>0x........</ip>
@@ -283,20 +247,10 @@
<file>hg_intercepts.c</file>
<line>...</line>
</frame>
- <frame>
- <ip>0x........</ip>
- <obj>...</obj>
- <fn>start_thread</fn>
- <dir>...</dir>
- <file>pthread_create.c</file>
- <line>...</line>
- </frame>
- <frame>
- <ip>0x........</ip>
- </frame>
+ <frame>...</frame>
</stack>
<auxwhat>Location 0x........ is 0 bytes inside global var "unprot2"</auxwhat>
- <xauxwhat><text>declared at tc06_two_races.c:9</text> <file>tc06_two_races.c</file> <line>...</line> </xauxwhat>
+ <xauxwhat><text>declared at tc06_two_races.c:9</text> <file>tc06_two_races.c</file> <line>9</line> </xauxwhat>
</error>
@@ -305,24 +259,7 @@
<time>...</time>
</status>
-<errorcounts>
- <pair>
- <count>...</count>
- <unique>0x........</unique>
- </pair>
- <pair>
- <count>...</count>
- <unique>0x........</unique>
- </pair>
- <pair>
- <count>...</count>
- <unique>0x........</unique>
- </pair>
- <pair>
- <count>...</count>
- <unique>0x........</unique>
- </pair>
-</errorcounts>
+<errorcounts>...</errorcounts>
<suppcounts>...</suppcounts>
diff --git a/helgrind/tests/tc06_two_races_xml.vgtest b/helgrind/tests/tc06_two_races_xml.vgtest
index 26f3e81..48c0528 100644
--- a/helgrind/tests/tc06_two_races_xml.vgtest
+++ b/helgrind/tests/tc06_two_races_xml.vgtest
@@ -1,3 +1,4 @@
prog: tc06_two_races
vgopts: --read-var-info=yes --xml=yes --xml-fd=2 --log-file=/dev/null
-stderr_filter: ../../memcheck/tests/filter_xml
+stderr_filter: ./filter_xml
+stderr_filter_args: tc06_two_races.c