def record_crasher(workerno: int, sampleno: int, minimize_ir: bool, sample: Sample, run_dir: Text, crash_path: Text, num_crashers: int): """Records and writes details of a failing test as a crasher.""" print('--- Worker {} observed an exception for sampleno {}'.format( workerno, sampleno)) # Try to prune down the IR to a minimal reproducer. if minimize_ir: print('--- Worker {} attempting to minimize IR'.format(workerno)) minimized_ir_path = run_fuzz.minimize_ir(sample, run_dir) if minimized_ir_path: print('--- Worker {} minimized IR saved in {}'.format( workerno, os.path.basename(minimized_ir_path))) else: print('--- Worker {} unable to minimize IR'.format(workerno)) # Create a directory under crash_path containing the entire contents of # the run directory along with a crasher file. Name of directory is the # first eight characters of the hash of the code sample. digest = hashlib.sha256(sample.input_text.encode('utf-8')).hexdigest()[:8] sample_crasher_dir = os.path.join(crash_path, digest) termcolor.cprint( '--- Worker {} noted crasher #{} for sampleno {} in {}'.format( workerno, num_crashers, sampleno, sample_crasher_dir), color='red') sys.stdout.flush() gfile.recursively_copy_dir( run_dir, sample_crasher_dir, preserve_file_mask=True) crasher_path = os.path.join( sample_crasher_dir, 'crasher_{}_{}.x'.format(datetime.date.today().strftime('%Y-%m-%d'), digest[:4])) with gfile.open(crasher_path, 'w') as f: f.write(sample.to_crasher())
def test_minimize_ir_minimization_possible(self): # Add an invalid codegen flag to inject an error into the running of the # sample. The error is unconditional so IR minimization should be able to # reduce the sample to a minimal function (just returns a parameter). s = sample.Sample( 'fn main(x: u8) -> u8 { -x }', sample.SampleOptions(codegen=True, codegen_args=('--invalid_flag!!!', )), sample.parse_args_batch('bits[8]:7\nbits[8]:100')) success = test_base.TempFileCleanup.SUCCESS # type: test_base.TempFileCleanup run_dir = self.create_tempdir(cleanup=success).full_path with self.assertRaises(sample_runner.SampleError): run_fuzz.run_sample(s, run_dir=run_dir) minimized_ir_path = run_fuzz.minimize_ir(s, run_dir) self.assertIsNotNone(minimized_ir_path) self.assertIn('ir_minimizer_test.sh', os.listdir(run_dir)) # Sanity check the minimized IR. with open(minimized_ir_path, 'r') as f: contents = f.read() self.assertIn('package ', contents) self.assertIn('fn ', contents) # It should be reduced to simply a literal. self.assertIn('ret literal', contents) # And verify the minimized IR parses. subprocess.check_call([PARSE_IR, minimized_ir_path])
def test_minimize_ir_no_minimization_possible(self): # Verify that IR minimization at least generates a minimization test script # and doesn't blow up if the IR is not minimizable. In this case, "not # minimizable" means that no error is ever generated when running the # sample. s = sample.Sample('fn main(x: u8) -> u8 { -x }', sample.SampleOptions(), sample.parse_args_batch('bits[8]:7\nbits[8]:100')) success = test_base.TempFileCleanup.SUCCESS # type: test_base.TempFileCleanup run_dir = self.create_tempdir(cleanup=success).full_path run_fuzz.run_sample(s, run_dir=run_dir) self.assertIsNone(run_fuzz.minimize_ir(s, run_dir)) dir_contents = os.listdir(run_dir) self.assertIn('ir_minimizer_test.sh', dir_contents)
def test_minimize_jit_interpreter_mismatch(self): s = sample.Sample('fn main(x: u8) -> u8 { !x }', sample.SampleOptions(), sample.parse_args_batch('bits[8]:0xff\nbits[8]:0x42')) success = test_base.TempFileCleanup.SUCCESS # type: test_base.TempFileCleanup run_dir = self.create_tempdir(cleanup=success).full_path run_fuzz.run_sample(s, run_dir=run_dir) minimized_ir_path = run_fuzz.minimize_ir( s, run_dir, inject_jit_result='bits[32]:0x0') self.assertIsNotNone(minimized_ir_path) with open(minimized_ir_path, 'r') as f: contents = f.read() self.assertIn('package ', contents) self.assertIn('fn ', contents) # It should be reduced to simply a literal. self.assertIn('ret literal', contents) # And verify the minimized IR parses. subprocess.check_call([PARSE_IR, minimized_ir_path])