114b11b2bSmrg#!/usr/bin/env perl 214b11b2bSmrg 314b11b2bSmrg$usage = "Usage: 414b11b2bSmrg fuzzer-find-diff.pl reference_binary new_binary [number_of_tests_to_run] 514b11b2bSmrg 614b11b2bSmrgThe first two input arguments are the commands to run the test programs 714b11b2bSmrgbased on fuzzer_test_main() function from 'util.c' (preferably they should 814b11b2bSmrgbe statically compiled, this can be achieved via '--disable-shared' pixman 914b11b2bSmrgconfigure option). The third optional argument is the number of test rounds 1014b11b2bSmrgto run (if not specified, then testing runs infinitely or until some problem 1114b11b2bSmrgis detected). 1214b11b2bSmrg 1314b11b2bSmrgUsage examples: 1414b11b2bSmrg fuzzer-find-diff.pl ./blitters-test-with-sse-disabled ./blitters-test 9000000 1514b11b2bSmrg fuzzer-find-diff.pl ./blitters-test \"ssh ppc64_host /path/to/blitters-test\" 1614b11b2bSmrg"; 1714b11b2bSmrg 1814b11b2bSmrg$#ARGV >= 1 or die $usage; 1914b11b2bSmrg 2014b11b2bSmrg$batch_size = 10000; 2114b11b2bSmrg 2214b11b2bSmrgif ($#ARGV >= 2) { 2314b11b2bSmrg $number_of_tests = int($ARGV[2]); 2414b11b2bSmrg} else { 2514b11b2bSmrg $number_of_tests = -1 2614b11b2bSmrg} 2714b11b2bSmrg 2814b11b2bSmrgsub test_range { 2914b11b2bSmrg my $min = shift; 3014b11b2bSmrg my $max = shift; 3114b11b2bSmrg 3214b11b2bSmrg # check that [$min, $max] range is "bad", otherwise return 3314b11b2bSmrg if (`$ARGV[0] $min $max 2>/dev/null` eq `$ARGV[1] $min $max 2>/dev/null`) { 3414b11b2bSmrg return; 3514b11b2bSmrg } 3614b11b2bSmrg 3714b11b2bSmrg # check that $min itself is "good", otherwise return 3814b11b2bSmrg if (`$ARGV[0] $min 2>/dev/null` ne `$ARGV[1] $min 2>/dev/null`) { 3914b11b2bSmrg return $min; 4014b11b2bSmrg } 4114b11b2bSmrg 4214b11b2bSmrg # start bisecting 4314b11b2bSmrg while ($max != $min + 1) { 4414b11b2bSmrg my $avg = int(($min + $max) / 2); 4514b11b2bSmrg my $res1 = `$ARGV[0] $min $avg 2>/dev/null`; 4614b11b2bSmrg my $res2 = `$ARGV[1] $min $avg 2>/dev/null`; 4714b11b2bSmrg if ($res1 ne $res2) { 4814b11b2bSmrg $max = $avg; 4914b11b2bSmrg } else { 5014b11b2bSmrg $min = $avg; 5114b11b2bSmrg } 5214b11b2bSmrg } 5314b11b2bSmrg return $max; 5414b11b2bSmrg} 5514b11b2bSmrg 5614b11b2bSmrg$base = 1; 5714b11b2bSmrgwhile ($number_of_tests <= 0 || $base <= $number_of_tests) { 5814b11b2bSmrg printf("testing %-12d\r", $base + $batch_size - 1); 5914b11b2bSmrg my $res = test_range($base, $base + $batch_size - 1); 6014b11b2bSmrg if ($res) { 6114b11b2bSmrg printf("Failure: results are different for test %d:\n", $res); 6214b11b2bSmrg 6314b11b2bSmrg printf("\n-- ref --\n"); 6414b11b2bSmrg print `$ARGV[0] $res`; 6514b11b2bSmrg printf("-- new --\n"); 6614b11b2bSmrg print `$ARGV[1] $res`; 6714b11b2bSmrg 6814b11b2bSmrg printf("The problematic conditions can be reproduced by running:\n"); 6914b11b2bSmrg printf("$ARGV[1] %d\n", $res); 7014b11b2bSmrg 7114b11b2bSmrg exit(1); 7214b11b2bSmrg } 7314b11b2bSmrg $base += $batch_size; 7414b11b2bSmrg} 7514b11b2bSmrgprintf("Success: %d tests finished\n", $base - 1); 76