1#!/usr/bin/env perl 2 3$usage = "Usage: 4 fuzzer-find-diff.pl reference_binary new_binary [number_of_tests_to_run] 5 6The first two input arguments are the commands to run the test programs 7based on fuzzer_test_main() function from 'util.c' (preferably they should 8be statically compiled, this can be achieved via '--disable-shared' pixman 9configure option). The third optional argument is the number of test rounds 10to run (if not specified, then testing runs infinitely or until some problem 11is detected). 12 13Usage examples: 14 fuzzer-find-diff.pl ./blitters-test-with-sse-disabled ./blitters-test 9000000 15 fuzzer-find-diff.pl ./blitters-test \"ssh ppc64_host /path/to/blitters-test\" 16"; 17 18$#ARGV >= 1 or die $usage; 19 20$batch_size = 10000; 21 22if ($#ARGV >= 2) { 23 $number_of_tests = int($ARGV[2]); 24} else { 25 $number_of_tests = -1 26} 27 28sub test_range { 29 my $min = shift; 30 my $max = shift; 31 32 # check that [$min, $max] range is "bad", otherwise return 33 if (`$ARGV[0] $min $max 2>/dev/null` eq `$ARGV[1] $min $max 2>/dev/null`) { 34 return; 35 } 36 37 # check that $min itself is "good", otherwise return 38 if (`$ARGV[0] $min 2>/dev/null` ne `$ARGV[1] $min 2>/dev/null`) { 39 return $min; 40 } 41 42 # start bisecting 43 while ($max != $min + 1) { 44 my $avg = int(($min + $max) / 2); 45 my $res1 = `$ARGV[0] $min $avg 2>/dev/null`; 46 my $res2 = `$ARGV[1] $min $avg 2>/dev/null`; 47 if ($res1 ne $res2) { 48 $max = $avg; 49 } else { 50 $min = $avg; 51 } 52 } 53 return $max; 54} 55 56$base = 1; 57while ($number_of_tests <= 0 || $base <= $number_of_tests) { 58 printf("testing %-12d\r", $base + $batch_size - 1); 59 my $res = test_range($base, $base + $batch_size - 1); 60 if ($res) { 61 printf("Failure: results are different for test %d:\n", $res); 62 63 printf("\n-- ref --\n"); 64 print `$ARGV[0] $res`; 65 printf("-- new --\n"); 66 print `$ARGV[1] $res`; 67 68 printf("The problematic conditions can be reproduced by running:\n"); 69 printf("$ARGV[1] %d\n", $res); 70 71 exit(1); 72 } 73 $base += $batch_size; 74} 75printf("Success: %d tests finished\n", $base - 1); 76