1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#!/usr/bin/env perl 2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovuse strict; 3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovuse warnings; 4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov###################################################### 6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Binary search script for switchback 7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Finds bad basic block for seg faults and bad output. 8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# 9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# To test output, you need to create test_ref 10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# test_ref should hold the correct output for running the test_xxx program: 11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# - Everything between (not including) /^---START---$/ and /^---STOP---$/ 12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# - But NOT including output from /^---begin SWITCHBACK/ 13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# to /^--- end SWITCHBACK/ inclusive 14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# 15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# This script can't handle other vex output, 16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# so e.g switchback.c::DEBUG_TRACE_FLAGS should be 0 17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# 18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov###################################################### 20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Global consts, vars 21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovuse constant DEBUG => 0; 22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovuse constant CONST_N_MAX => 10000000000; 23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovuse constant CONST_N_MUL => 2; 24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $SWITCHBACK = "./switchback"; 26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $N_START = 0; 27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $N_LAST_GOOD = 0; 28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $N_LAST_BAD = -1; 29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $GIVEN_LAST_GOOD = -1; 30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $GIVEN_LAST_BAD = -1; 31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $TEST_REF; 32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov###################################################### 36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Helper functions 37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovsub Exit { 39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit $_[0]; 40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovsub Usage { 43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "Usage: binary_switchback.pl test_ref [last_good [last_bad]]\n"; 44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "where:\n"; 45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print " test_ref = reference output from test_xxx\n"; 46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print " last_good = last known good bb (search space minimum)\n"; 47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print " last_bad = last known bad bb (search space maximum)\n"; 48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "\n"; 49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovsub QuitUsage { 52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print $_[0]."\n"; 53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Usage(); 54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Exit 1; 55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov###################################################### 59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Get & check cmdline args 60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# - if given, override global vars. 61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif (@ARGV < 1 || @ARGV > 3) { 63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov QuitUsage "Error: Bad num args\n"; 64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov$TEST_REF = $ARGV[0]; 67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ( ! -x "$SWITCHBACK" ) { 69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov QuitUsage "File doesn't exist | not executable: '$SWITCHBACK'\n"; 70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif (@ARGV >1) { 73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $N_LAST_GOOD = $ARGV[1]; 74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $GIVEN_LAST_GOOD = $N_LAST_GOOD; 75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (! ($N_LAST_GOOD =~ /^\d*$/)) { 76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov QuitUsage "Error: bad arg for #last_good\n"; 77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($N_LAST_GOOD >= CONST_N_MAX) { 79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov QuitUsage "Error: #last_good >= N_MAX(".CONST_N_MAX.")\n"; 80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif (@ARGV >2) { 83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $N_LAST_BAD = $ARGV[2]; 84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $GIVEN_LAST_BAD = $N_LAST_BAD; 85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (! ($N_LAST_BAD =~ /^\d*$/)) { 86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov QuitUsage "Error: bad arg for 'last_bad'\n"; 87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Setup N_START 91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($N_LAST_BAD != -1) { 92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov # Start halfway: 93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $diff = $N_LAST_BAD - $N_LAST_GOOD; 94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $N_START = $N_LAST_GOOD + ($diff - ($diff % 2)) / 2; 95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} else { 96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov # No known end: Start at beginning: 97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($N_LAST_GOOD > 0) { # User-given last_good 98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $N_START = $N_LAST_GOOD; 99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $N_START = 100; # Some reasonable number. 101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov###################################################### 105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Sanity checks (shouldn't ever happen) 106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($N_START < $N_LAST_GOOD) { 108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "Program Error: start < last_good\n"; 109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit 1; 110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($N_LAST_BAD != -1 && $N_START >= $N_LAST_BAD) { 112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "Program Error: start >= last_bad\n"; 113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit 1; 114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($N_START < 1 || $N_START > CONST_N_MAX) { 116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "Program Error: Bad N_START: '$N_START'\n"; 117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit 1; 118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($N_LAST_GOOD < 0 || $N_LAST_GOOD > CONST_N_MAX) { 120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "Program Error: Bad N_LAST_GOOD: '$N_LAST_GOOD'\n"; 121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit 1; 122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($N_LAST_BAD < -1 || $N_LAST_BAD > CONST_N_MAX) { 124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "Program Error: Bad N_LAST_BAD: '$N_LAST_BAD'\n"; 125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit 1; 126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov###################################################### 134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Helper functions 135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Run switchback for test, for N bbs 137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# returns output results 138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovsub SwitchBack { 139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $n = $_[0]; 140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($n < 0 || $n > CONST_N_MAX) { 141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "Error SwitchBack: Bad N: '$n'\n"; 142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Exit 1; 143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $TMPFILE = ".switchback_output.$n"; 145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "=== Calling switchback for bb $n ===\n"; 147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov system("$SWITCHBACK $n >& $TMPFILE"); 149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $ret = $?; 150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($ret == 256) { 152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "Error running switchback - Quitting...\n---\n"; 153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov open(INFILE, "$TMPFILE"); 154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print <INFILE>; 155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov close(INFILE); 156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unlink($TMPFILE) if (! DEBUG); 158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit 0; 159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($ret & 127) { 162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "Ctrl-C pressed - Quitting...\n"; 163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unlink($TMPFILE) if (! DEBUG); 164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit 0; 165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (DEBUG) { 168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($ret == -1) { 169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "failed to execute: $!\n"; 170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov elsif ($ret & 127) { 172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf "child died with signal %d, %s coredump\n", 173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ($ret & 127), ($ret & 128) ? 'with' : 'without'; 174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else { 176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf "child exited with value %d\n", $ret >> 8; 177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($ret != 0) { # Err: maybe seg fault 180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov open(INFILE, "$TMPFILE"); 181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my @results = <INFILE>; 182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov close(INFILE); 183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (@results && !((shift @results) =~ /^---START---/)) {} 185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print @results; 186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unlink($TMPFILE) if (! DEBUG); 188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return; 189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov open(INFILE, "$TMPFILE"); 192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my @results = <INFILE>; 193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov close(INFILE); 194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unlink($TMPFILE) if (! DEBUG); 196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return @results; 197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Returns N simulated bbs from output lines 200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovsub get_N_simulated { 201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my @lines = @{$_[0]}; 202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pop @lines; # not the first... 203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $line = pop @lines; # ...but the second line. 204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov chomp $line; 206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $n; 207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (($n) = ($line =~ /^(\d*) bbs simulated$/)) { 208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return $n; 209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "Error: Didn't find N bbs simultated, from output lines\n"; 211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Exit 1; 212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Calls test script to compare current output lines with a reference. 215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Returns 1 on success, 0 on failure 216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovsub TestOutput { 217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my @lines = @{$_[0]}; 218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $n = $_[1]; 219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $ref_output = "$TEST_REF"; 220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov # Get the current section we want to compare: 222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my @newlines; 223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $ok=0; 224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $halfline = ""; 225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov foreach my $line(@lines) { 226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov chomp $line; 227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($line =~ /^---STOP---$/) { last; } # we're done 228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov # output might be messed up here... 230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($line =~ /^.*---begin SWITCHBACK/) { 231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ($halfline) = ($line =~ /^(.*)---begin SWITCHBACK/); 232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $ok = 0; # stop on prev line 233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov # A valid line: 236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($ok) { 237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($halfline ne "") { # Fix broken line 238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $line = $halfline.$line; 239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $halfline = ""; 240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov # Ignore Vex output 243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($line =~ /^vex /) { next; } 244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov push(@newlines, $line); 246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($line =~ /^---START---$/) { # start on next line 249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $ok = 1; 250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($line =~ /^--- end SWITCHBACK/) { # start on next line 253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $ok = 1; 254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (DEBUG) { 259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov open(OUTFILE, ">.filtered_output.$n"); 260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print OUTFILE join("\n",@newlines); 261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov close(OUTFILE); 262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov # Read in reference lines 265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov open(REFERENCE, "$ref_output") || die "Error: Couldn't open $ref_output\n"; 266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my @ref_lines = <REFERENCE>; 267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov close(REFERENCE); 268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov # Compare reference lines with current: 270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $match = 1; 271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $i = 0; 272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov foreach my $ref_line(@ref_lines) { 273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov chomp $ref_line; 274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $line = $newlines[$i++]; 275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov chomp $line; 276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($ref_line ne $line) { 277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "\nMismatch on output:\n"; 278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "ref: '$ref_line'\n"; 279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "new: '$line'\n\n"; 280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $match = 0; 281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov last; 282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return $match; 285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov###################################################### 293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Do the search 294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif (DEBUG) { 296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "\n------------\n"; 297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "START: N=$N_START\n"; 298b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "START: lg=$N_LAST_GOOD\n"; 299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "START: lb=$N_LAST_BAD\n"; 300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "START: GIVEN_LAST_GOOD=$GIVEN_LAST_GOOD\n"; 301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "START: GIVEN_LAST_BAD =$GIVEN_LAST_BAD\n"; 302b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "\n"; 303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $N = $N_START; 306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $success = 0; 307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy @sb_output; 308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovwhile (1) { 309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (DEBUG) { 310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "\n------------\n"; 311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "SOL: lg=$N_LAST_GOOD\n"; 312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "SOL: lb=$N_LAST_BAD\n"; 313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "SOL: N=$N\n"; 314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($N < 0) { 316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "Error: $N<0\n"; 317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Exit 1; 318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $ok = 1; 321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov # Run switchback: 322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov @sb_output = SwitchBack($N); 323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (@sb_output == 0) { # Switchback failed - maybe seg fault 325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $ok = 0; 326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (DEBUG) { 329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov open(fileOUT, ">.retrieved_output.$N") or die("Can't open file for writing: $!"); 330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print fileOUT @sb_output; 331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov close(fileOUT); 332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov # If we're ok so far (no seg faults) then test for correct output 335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($ok) { 336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $ok = TestOutput( \@sb_output, $N ); 337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($ok) { 340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (get_N_simulated(\@sb_output) < $N) { # Done: No bad bbs 341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $success = 1; 342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov last; 343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($N_LAST_BAD == -1) { 345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov # No upper bound for search space 346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov # Try again with a bigger N 347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $N_LAST_GOOD = $N; 349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $N *= CONST_N_MUL; 350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($N > CONST_N_MAX) { 351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "\nError: Maxed out N($N): N_MAX=".CONST_N_MAX."\n"; 352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "\nWe're either in a loop, or this is a big test program (increase N_MAX)\n\n"; 353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Exit 1; 354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (DEBUG) { 356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "Looks good so far: Trying bigger N...\n\n"; 357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov next; 359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov # Narrow the search space: 363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($ok) { $N_LAST_GOOD = $N; } 364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else { $N_LAST_BAD = $N; } 365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov # Calculate next step: 367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $diff = $N_LAST_BAD - $N_LAST_GOOD; 368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $diff = $diff - ($diff % 2); 369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my $step = $diff / 2; 370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($step < 0) { 372b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "Error: step = $step\n"; 373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Exit 1; 374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 376b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov # This our last run-through? 377b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($step!=0) { 378b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $N = $N_LAST_GOOD + $step; # Keep on going... 379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov last; # Get outta here 381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 382b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (DEBUG) { 384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "\nEOL: ok=$ok\n"; 385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "EOL: lg=$N_LAST_GOOD\n"; 386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "EOL: lb=$N_LAST_BAD\n"; 387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "EOL: s=$step\n"; 388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "EOL: N=$N\n"; 389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 394b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov###################################################### 395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Done: Report results 396b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 397b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovprint "\n============================================\n"; 398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovprint "Done searching.\n\n"; 399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($N_LAST_BAD != -1 && $N != $N_LAST_BAD) { 401b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "Getting output for last bad bb:\n"; 402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov @sb_output = SwitchBack($N_LAST_BAD); 403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovprint @sb_output; 406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovprint "\n\n"; 407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif ($success) { 408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "*** Success! No bad bbs found. ***\n"; 409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} else { 410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($N_LAST_BAD == $GIVEN_LAST_BAD) { 411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "*** No failures detected within given bb range ***\n"; 412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print " - check given 'last_bad' argument\n"; 413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ($N_LAST_BAD == $GIVEN_LAST_GOOD) { 415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "*** Failed on bb given as last_good ***\n"; 416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print " - decrease the 'last_good' argument\n"; 417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "*** Failure: Last failed switchback bb: $N_LAST_BAD ***\n"; 419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "Hence bad bb: ". ($N_LAST_BAD - 1) ."\n"; 420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovprint "\n"; 424b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovif (DEBUG) { 425b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "END: N=$N\n"; 426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "END: lg=$N_LAST_GOOD\n"; 427b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "END: lb=$N_LAST_BAD\n"; 428b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "END: GIVEN_LAST_BAD=$GIVEN_LAST_BAD\n"; 429b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov print "\n"; 430b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 431b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovExit 0; 432