def verify_bpl_svcomp(args): """Verify the Boogie source file using SVCOMP-tuned heuristics.""" heurTrace = "\n\nHeuristics Info:\n" # invoke boogie for floats # I have to copy/paste part of verify_bpl if args.float: args.verifier = 'boogie' boogie_command = ["boogie"] boogie_command += [args.bpl_file] boogie_command += ["/nologo", "/noinfer", "/doModSetAnalysis"] boogie_command += ["/timeLimit:%s" % args.time_limit] boogie_command += ["/errorLimit:%s" % args.max_violations] boogie_command += ["/loopUnroll:%d" % args.unroll] if args.bit_precise: x = "bopt:" if args.verifier != 'boogie' else "" boogie_command += ["/%sproverOpt:OPTIMIZE_FOR_BV=true" % x] boogie_command += ["/%sz3opt:smt.relevancy=0" % x] boogie_command += ["/%sz3opt:smt.bv.enable_int2bv=true" % x] boogie_command += ["/%sboolControlVC" % x] if args.verifier_options: boogie_command += args.verifier_options.split() boogie_output = smack.top.try_command(boogie_command, timeout=args.time_limit) boogie_result = smack.top.verification_result(boogie_output) write_error_file(args, boogie_result, boogie_output) sys.exit(smack.top.results(args)[boogie_result]) # If pthreads found, perform lock set analysis if args.pthread: lockpwn_command = ["lockpwn"] lockpwn_command += [args.bpl_file] lockpwn_command += ["/corral"] args.bpl_file = smack.top.temporary_file(os.path.splitext(os.path.basename(args.bpl_file))[0], '.bpl', args) lockpwn_command += ["/o:%s" % args.bpl_file] lockpwn_output = smack.top.try_command(lockpwn_command); corral_command = ["corral"] corral_command += [args.bpl_file] corral_command += ["/tryCTrace", "/noTraceOnDisk", "/printDataValues:1"] corral_command += ["/useProverEvaluate", "/cex:1"] with open(args.bpl_file, "r") as f: bpl = f.read() is_crappy_driver_benchmark(args, bpl) if args.pthread: if "fib_bench" in bpl or "27_Boop_simple_vf_false-unreach-call" in bpl: heurTrace += "Increasing context switch bound for certain pthread benchmarks.\n" corral_command += ["/k:30"] else: corral_command += ["/k:3"] if not "qrcu_reader2" in bpl and not "__VERIFIER_atomic_take_write_lock" in bpl and not "fib_bench" in bpl: corral_command += ["/cooperative"] else: corral_command += ["/k:1"] if not args.memory_safety or not args.bit_precise: corral_command += ["/di"] # we are not modeling strcpy if args.pthread and "strcpy" in bpl: heurTrace += "We are not modeling strcpy - aborting\n" if not args.quiet: print(heurTrace + "\n") sys.exit(smack.top.results(args)['unknown']) # Setting good loop unroll bound based on benchmark class loopUnrollBar = 8 staticLoopBound = 65536 if not args.bit_precise and "ssl3_accept" in bpl and "s__s3__tmp__new_cipher__algorithms" in bpl: heurTrace += "ControlFlow benchmark detected. Setting loop unroll bar to 23.\n" loopUnrollBar = 23 elif "s3_srvr.blast.10_false-unreach-call" in bpl or "s3_srvr.blast.15_false-unreach-call" in bpl: heurTrace += "ControlFlow benchmark detected. Setting loop unroll bar to 23.\n" loopUnrollBar = 23 elif " node3" in bpl: heurTrace += "Sequentialized benchmark detected. Setting loop unroll bar to 100.\n" loopUnrollBar = 100 elif "calculate_output" in bpl: heurTrace += "ECA benchmark detected. Setting loop unroll bar to 15.\n" loopUnrollBar = 15 elif "ldv" in bpl: if "linux-4.2-rc1.tar.xz-08_1a-drivers--staging--lustre--lustre--llite--llite_lloop.ko-entry_point_false-unreach-call" in bpl: heurTrace += "Special LDV benchmark detected. Setting loop unroll bar to 32.\n" loopUnrollBar = 32 else: heurTrace += "LDV benchmark detected. Setting loop unroll bar to 13.\n" loopUnrollBar = 13 staticLoopBound = 64 elif "standard_strcpy_false-valid-deref_ground_true-termination" in bpl or "960521-1_false-valid-free" in bpl or "960521-1_false-valid-deref" in bpl or "lockfree-3.3" in bpl: heurTrace += "Memory safety benchmark detected. Setting loop unroll bar to 129.\n" loopUnrollBar = 129 elif "is_relaxed_prefix" in bpl: heurTrace += "Benchmark relax_* detected. Setting loop unroll bar to 15.\n" loopUnrollBar = 15 elif "id_o1000_false-unreach-call" in bpl: heurTrace += "Recursive benchmark detected. Setting loop unroll bar to 1024.\n" loopUnrollBar = 1024 elif args.memory_safety and "__main(argc:" in bpl: heurTrace += "BusyBox memory safety benchmark detected. Setting loop unroll bar to 128.\n" loopUnrollBar = 128 elif args.signed_integer_overflow and "__main(argc:" in bpl: heurTrace += "BusyBox overflows benchmark detected. Setting loop unroll bar to 11.\n" loopUnrollBar = 11 elif args.signed_integer_overflow and "jain" in bpl: heurTrace += "Infinite loop in overflow benchmark. Setting loop unroll bar to INT_MAX.\n" loopUnrollBar = 2**31 - 1 if not "forall" in bpl: heurTrace += "No quantifiers detected. Setting z3 relevancy to 0.\n" corral_command += ["/bopt:z3opt:smt.relevancy=0"] if args.bit_precise: heurTrace += "--bit-precise flag passed - enabling bit vectors mode.\n" corral_command += ["/bopt:proverOpt:OPTIMIZE_FOR_BV=true"] corral_command += ["/bopt:boolControlVC"] time_limit = 880 command = list(corral_command) command += ["/timeLimit:%s" % time_limit] command += ["/v:1"] command += ["/maxStaticLoopBound:%d" % staticLoopBound] command += ["/recursionBound:65536"] command += ["/irreducibleLoopUnroll:2"] command += ["/trackAllVars"] verifier_output = smack.top.try_command(command, timeout=time_limit) result = smack.top.verification_result(verifier_output) if result == 'error' or result == 'invalid-deref' or result == 'invalid-free' or result == 'invalid-memtrack' or result == 'overflow': #normal inlining heurTrace += "Found a bug during normal inlining.\n" if not args.quiet: error = smack.top.error_trace(verifier_output, args) print error elif result == 'timeout': #normal inlining heurTrace += "Timed out during normal inlining.\n" heurTrace += "Determining result based on how far we unrolled.\n" # If we managed to unroll more than loopUnrollBar times, then return verified # First remove exhausted loop bounds generated during max static loop bound computation unrollMax = 0 if 'Verifying program while tracking' in verifier_output: verifier_output = re.sub(re.compile('.*Verifying program while tracking', re.DOTALL), 'Verifying program while tracking', verifier_output) it = re.finditer(r'Exhausted recursion bound of ([1-9]\d*)', verifier_output) for match in it: if int(match.group(1)) > unrollMax: unrollMax = int(match.group(1)) else: heurTrace += "Corral didn't even start verification.\n" if unrollMax >= loopUnrollBar: heurTrace += "Unrolling made it to a recursion bound of " heurTrace += str(unrollMax) + ".\n" heurTrace += "Reporting benchmark as 'verified'.\n" if args.execute and not args.pthread: heurTrace += "Hold on, let's see the execution result.\n" execution_result = run_binary(args) heurTrace += "Excecution result is " + execution_result + '\n' if execution_result != 'true': heurTrace += "Oops, execution result says {0}.\n".format(execution_result) if not args.quiet: print(heurTrace + "\n") sys.exit(smack.top.results(args)['unknown']) random_test_result = random_test(args, result) if random_test_result == 'false' or random_test_result == 'unknown': heurTrace += "Oops, random testing says {0}.\n".format(random_test_result) if not args.quiet: print(heurTrace + "\n") sys.exit(smack.top.results(args)['unknown']) if not args.quiet: print(heurTrace + "\n") write_error_file(args, 'verified', verifier_output) sys.exit(smack.top.results(args)['verified']) else: heurTrace += "Only unrolled " + str(unrollMax) + " times.\n" heurTrace += "Insufficient unrolls to consider 'verified'. " heurTrace += "Reporting 'timeout'.\n" if not args.quiet: print(heurTrace + "\n") sys.stdout.flush() # Sleep for 1000 seconds, so svcomp shows timeout instead of unknown time.sleep(1000) elif result == 'verified': #normal inlining heurTrace += "Normal inlining terminated and found no bugs.\n" else: #normal inlining heurTrace += "Normal inlining returned 'unknown'. See errors above.\n" if not args.quiet: print(heurTrace + "\n") write_error_file(args, result, verifier_output) sys.exit(smack.top.results(args)[result])
def verify_bpl_svcomp(args): """Verify the Boogie source file using SVCOMP-tuned heuristics.""" heurTrace = "\n\nHeuristics Info:\n" if args.memory_safety: if not (args.only_check_valid_deref or args.only_check_valid_free or args.only_check_memleak): heurTrace = "engage valid deference checks.\n" args.only_check_valid_deref = True args.prop_to_check = 'valid-deref' args.bpl_with_all_props = smack.top.temporary_file(os.path.splitext(os.path.basename(args.bpl_file))[0], '.bpl', args) copyfile(args.bpl_file, args.bpl_with_all_props) smack.top.property_selection(args) elif args.only_check_valid_deref: heurTrace = "engage valid free checks.\n" args.only_check_valid_free = True args.prop_to_check = 'valid-free' args.only_check_valid_deref = False args.bpl_file = smack.top.temporary_file(os.path.splitext(os.path.basename(args.bpl_file))[0], '.bpl', args) copyfile(args.bpl_with_all_props, args.bpl_file) smack.top.property_selection(args) elif args.only_check_valid_free: heurTrace = "engage memleak checks.\n" args.only_check_memleak = True args.prop_to_check = 'memleak' args.only_check_valid_free = False args.bpl_file = smack.top.temporary_file(os.path.splitext(os.path.basename(args.bpl_file))[0], '.bpl', args) copyfile(args.bpl_with_all_props, args.bpl_file) smack.top.property_selection(args) # invoke boogie for floats # I have to copy/paste part of verify_bpl if args.float: args.verifier = 'boogie' boogie_command = ["boogie"] boogie_command += [args.bpl_file] boogie_command += ["/nologo", "/noinfer", "/doModSetAnalysis"] boogie_command += ["/timeLimit:%s" % args.time_limit] boogie_command += ["/errorLimit:%s" % args.max_violations] boogie_command += ["/loopUnroll:%d" % args.unroll] if args.bit_precise: x = "bopt:" if args.verifier != 'boogie' else "" boogie_command += ["/%sproverOpt:OPTIMIZE_FOR_BV=true" % x] boogie_command += ["/%sz3opt:smt.relevancy=0" % x] boogie_command += ["/%sz3opt:smt.bv.enable_int2bv=true" % x] boogie_command += ["/%sboolControlVC" % x] if args.verifier_options: boogie_command += args.verifier_options.split() boogie_output = smack.top.try_command(boogie_command, timeout=args.time_limit) boogie_result = smack.top.verification_result(boogie_output) write_error_file(args, boogie_result, boogie_output) sys.exit(smack.top.results(args)[boogie_result]) # If pthreads found, perform lock set analysis if args.pthread: lockpwn_command = ["lockpwn"] lockpwn_command += [args.bpl_file] lockpwn_command += ["/corral"] args.bpl_file = smack.top.temporary_file(os.path.splitext(os.path.basename(args.bpl_file))[0], '.bpl', args) lockpwn_command += ["/o:%s" % args.bpl_file] lockpwn_output = smack.top.try_command(lockpwn_command); corral_command = ["corral"] corral_command += [args.bpl_file] corral_command += ["/tryCTrace", "/noTraceOnDisk", "/printDataValues:1"] corral_command += ["/useProverEvaluate", "/cex:1"] with open(args.bpl_file, "r") as f: bpl = f.read() is_crappy_driver_benchmark(args, bpl) if args.pthread: if "fib_bench" in bpl or "27_Boop_simple_vf_false-unreach-call" in bpl: heurTrace += "Increasing context switch bound for certain pthread benchmarks.\n" corral_command += ["/k:30"] else: corral_command += ["/k:3"] if not "qrcu_reader2" in bpl and not "__VERIFIER_atomic_take_write_lock" in bpl and not "fib_bench" in bpl: corral_command += ["/cooperative"] else: corral_command += ["/k:1"] if not (args.memory_safety or args.bit_precise): corral_command += ["/di"] # we are not modeling strcpy if args.pthread and "strcpy" in bpl: heurTrace += "We are not modeling strcpy - aborting\n" if not args.quiet: print(heurTrace + "\n") sys.exit(smack.top.results(args)['unknown']) # Setting good loop unroll bound based on benchmark class loopUnrollBar = 8 staticLoopBound = 65536 if not args.bit_precise and "ssl3_accept" in bpl and "s__s3__tmp__new_cipher__algorithms" in bpl: heurTrace += "ControlFlow benchmark detected. Setting loop unroll bar to 23.\n" loopUnrollBar = 23 elif "s3_srvr.blast.10_false-unreach-call" in bpl or "s3_srvr.blast.15_false-unreach-call" in bpl: heurTrace += "ControlFlow benchmark detected. Setting loop unroll bar to 23.\n" loopUnrollBar = 23 elif "NonTerminationSimple4_false-no-overflow" in bpl: heurTrace += "Overflow benchmark detected. Setting loop unroll bar to 1024.\n" loopUnrollBar = 1024 elif " node3" in bpl: heurTrace += "Sequentialized benchmark detected. Setting loop unroll bar to 100.\n" loopUnrollBar = 100 elif "calculate_output" in bpl or "psyco" in bpl: heurTrace += "ECA benchmark detected. Setting loop unroll bar to 15.\n" loopUnrollBar = 15 elif "ldv" in bpl: if "linux-4.2-rc1.tar.xz-08_1a-drivers--staging--lustre--lustre--llite--llite_lloop.ko-entry_point" in bpl or "linux-3.14__complex_emg__linux-usb-dev__drivers-media-usb-hdpvr-hdpvr" in bpl: heurTrace += "Special LDV benchmark detected. Setting loop unroll bar to 32.\n" loopUnrollBar = 32 else: heurTrace += "LDV benchmark detected. Setting loop unroll bar to 13.\n" loopUnrollBar = 13 staticLoopBound = 64 elif "standard_strcpy_false-valid-deref_ground_true-termination" in bpl or "960521-1_false-valid-free" in bpl or "960521-1_false-valid-deref" in bpl or "lockfree-3.3" in bpl or "list-ext_false-unreach-call_false-valid-deref" in bpl: heurTrace += "Memory safety benchmark detected. Setting loop unroll bar to 129.\n" loopUnrollBar = 129 elif "is_relaxed_prefix" in bpl: heurTrace += "Benchmark relax_* detected. Setting loop unroll bar to 15.\n" loopUnrollBar = 15 elif "id_o1000_false-unreach-call" in bpl: heurTrace += "Recursive benchmark detected. Setting loop unroll bar to 1024.\n" loopUnrollBar = 1024 elif "n.c24" in bpl or "array_false-unreach-call3" in bpl: heurTrace += "Loops benchmark detected. Setting loop unroll bar to 1024.\n" loopUnrollBar = 1024 elif "printf_false-unreach-call" in bpl or "echo_true-no-overflow" in bpl: heurTrace += "BusyBox benchmark detected. Setting loop unroll bar to 11.\n" loopUnrollBar = 11 elif args.memory_safety and "__main($i0" in bpl: heurTrace += "BusyBox memory safety benchmark detected. Setting loop unroll bar to 4.\n" loopUnrollBar = 4 elif args.signed_integer_overflow and "__main($i0" in bpl: heurTrace += "BusyBox overflows benchmark detected. Setting loop unroll bar to 4.\n" loopUnrollBar = 4 elif args.signed_integer_overflow and ("jain" in bpl or "TerminatorRec02" in bpl or "NonTerminationSimple" in bpl): heurTrace += "Infinite loop in overflow benchmark. Setting loop unroll bar to INT_MAX.\n" loopUnrollBar = 2**31 - 1 if not "forall" in bpl: heurTrace += "No quantifiers detected. Setting z3 relevancy to 0.\n" corral_command += ["/bopt:z3opt:smt.relevancy=0"] if args.bit_precise: heurTrace += "--bit-precise flag passed - enabling bit vectors mode.\n" corral_command += ["/bopt:proverOpt:OPTIMIZE_FOR_BV=true"] corral_command += ["/bopt:boolControlVC"] if not args.bit_precise_pointers: corral_command += ["/bopt:z3opt:smt.bv.enable_int2bv=true"] if args.memory_safety: if args.prop_to_check == 'valid-deref': if "memleaks_test12_false-valid-free" in bpl: time_limit = 10 else: time_limit = 750 elif args.prop_to_check == 'valid-free': time_limit = 80 elif args.prop_to_check == 'memleak': time_limit = 50 else: time_limit = 880 command = list(corral_command) command += ["/timeLimit:%s" % time_limit] command += ["/v:1"] command += ["/maxStaticLoopBound:%d" % staticLoopBound] command += ["/recursionBound:65536"] command += ["/irreducibleLoopUnroll:2"] command += ["/trackAllVars"] verifier_output = smack.top.try_command(command, timeout=time_limit) result = smack.top.verification_result(verifier_output) if result == 'error' or result == 'invalid-deref' or result == 'invalid-free' or result == 'invalid-memtrack' or result == 'overflow': #normal inlining heurTrace += "Found a bug during normal inlining.\n" if not args.quiet: error = smack.top.error_trace(verifier_output, args) print error if args.memory_safety: heurTrace += (args.prop_to_check + "has errors\n") if args.prop_to_check == 'valid-free': if args.valid_deref_check_result != 'verified': force_timeout() elif args.prop_to_check == 'memleak': if args.valid_free_check_result == 'timeout': force_timeout() elif result == 'timeout': #normal inlining heurTrace += "Timed out during normal inlining.\n" heurTrace += "Determining result based on how far we unrolled.\n" # If we managed to unroll more than loopUnrollBar times, then return verified # First remove exhausted loop bounds generated during max static loop bound computation unrollMax = 0 if 'Verifying program while tracking' in verifier_output: verifier_output = re.sub(re.compile('.*Verifying program while tracking', re.DOTALL), 'Verifying program while tracking', verifier_output) it = re.finditer(r'Exhausted recursion bound of ([1-9]\d*)', verifier_output) for match in it: if int(match.group(1)) > unrollMax: unrollMax = int(match.group(1)) else: heurTrace += "Corral didn't even start verification.\n" if unrollMax >= loopUnrollBar: heurTrace += "Unrolling made it to a recursion bound of " heurTrace += str(unrollMax) + ".\n" heurTrace += "Reporting benchmark as 'verified'.\n" if args.execute and not args.pthread: heurTrace += "Hold on, let's see the execution result.\n" execution_result = run_binary(args) heurTrace += "Excecution result is " + execution_result + '\n' if execution_result != 'true': heurTrace += "Oops, execution result says {0}.\n".format(execution_result) if not args.quiet: print(heurTrace + "\n") sys.exit(smack.top.results(args)['unknown']) random_test_result = random_test(args, result) if random_test_result == 'false' or random_test_result == 'unknown': heurTrace += "Oops, random testing says {0}.\n".format(random_test_result) if not args.quiet: print(heurTrace + "\n") sys.exit(smack.top.results(args)['unknown']) if not args.quiet: print(heurTrace + "\n") if args.memory_safety: heurTrace += (args.prop_to_check + "is verified\n") if args.prop_to_check == 'valid-deref': args.valid_deref_check_result = 'verified' elif args.prop_to_check == 'valid-free': args.valid_free_check_result = 'verified' elif args.prop_to_check == 'memleak': if args.valid_deref_check_result == 'timeout': force_timeout() else: sys.exit(smack.top.results(args)[args.valid_deref_check_result]) verify_bpl_svcomp(args) else: write_error_file(args, 'verified', verifier_output) sys.exit(smack.top.results(args)['verified']) else: heurTrace += "Only unrolled " + str(unrollMax) + " times.\n" heurTrace += "Insufficient unrolls to consider 'verified'. " heurTrace += "Reporting 'timeout'.\n" if not args.quiet: print(heurTrace + "\n") sys.stdout.flush() if args.memory_safety: heurTrace += (args.prop_to_check + " times out\n") if args.prop_to_check == 'valid-deref': args.valid_deref_check_result = 'timeout' force_timeout() elif args.prop_to_check == 'valid-free': args.valid_free_check_result = 'timeout' elif args.prop_to_check == 'memleak': if args.valid_deref_check_result == 'timeout': force_timeout() else: sys.exit(smack.top.results(args)[args.valid_deref_check_result]) verify_bpl_svcomp(args) else: # Sleep for 1000 seconds, so svcomp shows timeout instead of unknown time.sleep(1000) elif result == 'verified': #normal inlining heurTrace += "Normal inlining terminated and found no bugs.\n" else: #normal inlining heurTrace += "Normal inlining returned 'unknown'. See errors above.\n" if not args.quiet: print(heurTrace + "\n") if args.memory_safety and result == 'verified': heurTrace += (args.prop_to_check + " is verified\n") if args.prop_to_check == 'valid-deref': args.valid_deref_check_result = 'verified' elif args.prop_to_check == 'valid-free': args.valid_free_check_result = 'verified' elif args.prop_to_check == 'memleak': if args.valid_deref_check_result == 'timeout': force_timeout() else: sys.exit(smack.top.results(args)[args.valid_deref_check_result]) verify_bpl_svcomp(args) else: write_error_file(args, result, verifier_output) sys.exit(smack.top.results(args)[result])
def refine_init( current_abs, init_cons_list, final_cons, initial_discrete_state, initial_controller_state, plant_sim, controller_sim, ci, pi, sampler, #plot, init_cons, original_plant_cons_list, MAX_ITER, sample_ci, pi_ref, ci_ref, opts): i = 1 while i <= MAX_ITER: print('iteration:', i) # TODO: temp function ss.init() (initial_state_set, final_state_set, is_final) = \ SS.init(current_abs, init_cons_list, final_cons, initial_discrete_state, initial_controller_state) system_params = SystemParams( initial_state_set, final_state_set, is_final, plant_sim, controller_sim, ci, pi, sampler, init_cons, final_cons, pi_ref, ci_ref ) SS.discover(current_abs, system_params) opts.plotting.show() if not system_params.final_state_set: print('did not find any abstract counter example!', file=SYS.stderr) return False print('analyzing graph...') pi_ref.cleanup() if ci_ref is not None: ci_ref.cleanup() # creates a new pi_ref, ci_ref (promising_initial_states, ci_seq_list, pi_seq_list) = current_abs.get_initial_states_from_error_paths(initial_state_set, final_state_set, pi_ref, ci_ref, pi, ci, opts.max_paths) # ##!!##logger.debug('promising initial states: {}'.format(promising_initial_states)) print('begin random testing!') #POFF # if plot: # f2 = plt.figure() # f2.suptitle('random testing') print(len(promising_initial_states), len(ci_seq_list), len(pi_seq_list)) #U.pause() # TODO: ugly...should it be another function? # Read the TODO above the function definition for more details (valid_promising_initial_state_list, pi_seq_list, ci_seq_list) = SS.filter_invalid_abs_states( promising_initial_states, pi_seq_list, ci_seq_list, current_abs, init_cons) print(len(valid_promising_initial_state_list), len(ci_seq_list), len(pi_seq_list)) #U.pause() if valid_promising_initial_state_list == []: print('no valid sample found during random testing. STOP', file=SYS.stderr) return False res = RT.random_test( current_abs, system_params, valid_promising_initial_state_list, ci_seq_list, pi_seq_list, init_cons, initial_discrete_state, initial_controller_state, sample_ci ) opts.plotting.show() if res: print('Concretized', file=SYS.stderr) fp.append_data(opts.op_fname, '{0} Concrete Traces({2}) for: {1} {0}\n'. format('='*20, opts.sys_path, len(res))) fp.append_data(opts.op_fname, '{}\n'.format(res)) return True (current_abs, init_cons_list) = SS.refine_init_based( current_abs, promising_initial_states, # should it not be valid_promising_initial_state_list? original_plant_cons_list)#, pi_ref, ci_ref) pi_ref.refine() if ci_ref is not None: ci_ref.refine() i += 1 print('Failed: MAX iterations {} exceeded'.format(MAX_ITER), file=SYS.stderr)
def falsify_using_model( current_abs, init_cons_list, final_cons, initial_discrete_state, initial_controller_state, plant_sim, controller_sim, ci, pi, sampler, #plot, init_cons, original_plant_cons_list, MAX_ITER, sample_ci, pi_ref, ci_ref, opts, sys_sim, sys, prop): # TODO: temp function ss.init() (initial_state_set, final_state_set, is_final) = \ SS.init(current_abs, init_cons_list, final_cons, initial_discrete_state, initial_controller_state) system_params = SystemParams( initial_state_set, final_state_set, is_final, plant_sim, controller_sim, ci, pi, sampler, init_cons, final_cons, pi_ref, ci_ref ) SS.discover(current_abs, system_params) opts.plotting.show() if not system_params.final_state_set: print('did not find any abstract counter example!', file=SYS.stderr) return False print('analyzing graph...') # creates a new pi_ref, ci_ref (error_paths, ci_seq_list, pi_seq_list) = current_abs.get_error_paths(initial_state_set, final_state_set, pi_ref, ci_ref, pi, ci, opts.max_paths) print('Refining...') if opts.refine == 'model-dft': import modelrefine as MR MR.refine_dft_model_based(current_abs, error_paths, pi_seq_list, system_params, sys_sim, opts, sys, prop) elif opts.refine == 'model-dmt': import modelrefine as MR MR.refine_dmt_model_based(current_abs, error_paths, pi_seq_list, system_params, sys_sim, opts, sys, prop) elif opts.refine == 'model-dct': import modelrefine as MR raise NotImplementedError elif opts.refine == 'model-rel': import modelrefine as MR MR.refine_rel_model_based(current_abs, error_paths, pi_seq_list, system_params, sys_sim, opts, sys, prop) else: assert(False) exit() print('begin random testing!') print(len(promising_initial_states), len(ci_seq_list), len(pi_seq_list)) (valid_promising_initial_state_list, pi_seq_list, ci_seq_list) = SS.filter_invalid_abs_states(promising_initial_states, pi_seq_list, ci_seq_list, current_abs, init_cons) print(len(valid_promising_initial_state_list), len(ci_seq_list), len(pi_seq_list)) if valid_promising_initial_state_list == []: print('no valid sample found for random testing. STOP', file=SYS.stderr) return False res = RT.random_test( current_abs, system_params, valid_promising_initial_state_list, ci_seq_list, pi_seq_list, init_cons, initial_discrete_state, initial_controller_state, sample_ci ) if res: print('Concretized', file=SYS.stderr) fp.append_data(opts.op_fname, '{0} Concrete Traces({2}) for: {1} {0}\n'. format('='*20, opts.sys_path, len(res))) fp.append_data(opts.op_fname, '{}\n'.format(res)) return True
def refine_trace( current_abs, init_cons_list, final_cons, initial_discrete_state, initial_controller_state, plant_sim, controller_sim, ci, pi, sampler, #plot, init_cons, original_plant_cons_list): (initial_state_set, final_state_set, is_final) = \ SS.init(current_abs, init_cons_list, final_cons, initial_discrete_state, initial_controller_state) system_params = SystemParams( initial_state_set, final_state_set, is_final, plant_sim, controller_sim, ci, pi, sampler, init_cons, final_cons, ) SS.discover(current_abs, system_params) #POFF # if plot: # plt.autoscale() # plt.show() while True: if not system_params.final_state_set: print('did not find any abstract counter example!', file=SYS.stderr) return True else: print('analyzing graph...') (promising_initial_states, ci_seq_list) = \ current_abs.get_initial_states_from_error_paths(initial_state_set, final_state_set) # ##!!##logger.debug('promising initial states: {}'.format(promising_initial_states)) print('begin random testing!') #POFF # if plot: # f2 = plt.figure() # f2.suptitle('random testing') # TODO: ugly...should it be another function? # Read the TODO above the function definition for more details valid_promising_initial_state_list = SS.filter_invalid_abs_states( promising_initial_states, current_abs, init_cons) if valid_promising_initial_state_list == []: print('no valid sample found during random testing. STOP', file=SYS.stderr) return True done = RT.random_test( current_abs, system_params, valid_promising_initial_state_list, ci_seq_list, init_cons, initial_discrete_state, initial_controller_state, ) #POFF # if plot: # plt.show() if done: print('Concretized', file=SYS.stderr) return True current_abs = SS.refine_trace_based( current_abs, current_abs.compute_error_paths(initial_state_set, final_state_set), system_params)
def verify_bpl_svcomp(args): """Verify the Boogie source file using SVCOMP-tuned heuristics.""" heurTrace = "\n\nHeuristics Info:\n" if args.memory_safety: if not (args.only_check_valid_deref or args.only_check_valid_free or args.only_check_memleak): heurTrace = "engage valid deference checks.\n" args.only_check_valid_deref = True args.prop_to_check = 'valid-deref' args.bpl_with_all_props = smack.top.temporary_file(os.path.splitext(os.path.basename(args.bpl_file))[0], '.bpl', args) copyfile(args.bpl_file, args.bpl_with_all_props) smack.top.property_selection(args) elif args.only_check_valid_deref: heurTrace = "engage valid free checks.\n" args.only_check_valid_free = True args.prop_to_check = 'valid-free' args.only_check_valid_deref = False args.bpl_file = smack.top.temporary_file(os.path.splitext(os.path.basename(args.bpl_file))[0], '.bpl', args) copyfile(args.bpl_with_all_props, args.bpl_file) smack.top.property_selection(args) elif args.only_check_valid_free: heurTrace = "engage memleak checks.\n" args.only_check_memleak = True args.prop_to_check = 'memleak' args.only_check_valid_free = False args.bpl_file = smack.top.temporary_file(os.path.splitext(os.path.basename(args.bpl_file))[0], '.bpl', args) copyfile(args.bpl_with_all_props, args.bpl_file) smack.top.property_selection(args) elif args.only_check_memcleanup: heurTrace = "engage memcleanup checks.\n" args.only_check_memleak = True smack.top.property_selection(args) args.only_check_memleak = False # If pthreads found, perform lock set analysis if args.pthread: lockpwn_command = ["lockpwn"] lockpwn_command += [args.bpl_file] lockpwn_command += ["/corral"] args.bpl_file = smack.top.temporary_file(os.path.splitext(os.path.basename(args.bpl_file))[0], '.bpl', args) lockpwn_command += ["/o:%s" % args.bpl_file] lockpwn_output = smack.top.try_command(lockpwn_command); corral_command = ["corral"] corral_command += [args.bpl_file] corral_command += ["/tryCTrace", "/noTraceOnDisk", "/printDataValues:1"] corral_command += ["/useProverEvaluate", "/cex:1"] with open(args.bpl_file, "r") as f: bpl = f.read() with open(args.input_files[0], "r") as f: csource = f.read() if args.memory_safety: is_stack_benchmark(args, csource) else: if "angleInRadian" in csource: if not args.quiet: print("Stumbled upon trigonometric function is float benchmark\n") sys.exit(smack.top.results(args)['unknown']) elif "copysign(1" in csource: if not args.quiet: print("Stumbled upon tricky float benchmark\n") sys.exit(smack.top.results(args)['unknown']) is_buggy_driver_benchmark(args, bpl) if args.pthread: if "fib_bench" in bpl or "27_Boop_simple_vf_false-unreach-call" in bpl or "k < 5;" in csource or "k < 10;" in csource or "k < 20;" in csource: heurTrace += "Increasing context switch bound for certain pthread benchmarks.\n" corral_command += ["/k:30"] else: corral_command += ["/k:3"] if not "qrcu_reader2" in bpl and not "__VERIFIER_atomic_take_write_lock" in bpl and not "fib_bench" in bpl: corral_command += ["/cooperative"] else: corral_command += ["/k:1"] if not (args.memory_safety or args.bit_precise or args.only_check_memcleanup): if not ("dll_create" in csource or "sll_create" in csource or "changeMethaneLevel" in csource): corral_command += ["/di"] # we are not modeling strcpy if args.pthread and "strcpy" in bpl: heurTrace += "We are not modeling strcpy - aborting\n" if not args.quiet: print(heurTrace + "\n") sys.exit(smack.top.results(args)['unknown']) # Setting good loop unroll bound based on benchmark class loopUnrollBar = 8 staticLoopBound = 65536 if not args.bit_precise and "ssl3_accept" in bpl and "s__s3__tmp__new_cipher__algorithms" in bpl: heurTrace += "ControlFlow benchmark detected. Setting loop unroll bar to 23.\n" loopUnrollBar = 23 elif "s3_srvr.blast.10_false-unreach-call" in bpl or "s3_srvr.blast.15_false-unreach-call" in bpl: heurTrace += "ControlFlow benchmark detected. Setting loop unroll bar to 23.\n" loopUnrollBar = 23 elif "NonTerminationSimple4_false-no-overflow" in bpl: heurTrace += "Overflow benchmark detected. Setting loop unroll bar to 1024.\n" loopUnrollBar = 1024 elif " node3" in bpl: heurTrace += "Sequentialized benchmark detected. Setting loop unroll bar to 100.\n" loopUnrollBar = 100 elif "calculate_output" in bpl or "psyco" in bpl: heurTrace += "ECA benchmark detected. Setting loop unroll bar to 15.\n" loopUnrollBar = 15 elif "ldv" in bpl: if "linux-4.2-rc1.tar.xz-08_1a-drivers--staging--lustre--lustre--llite--llite_lloop.ko-entry_point" in bpl or "linux-3.14__complex_emg__linux-usb-dev__drivers-media-usb-hdpvr-hdpvr" in bpl: heurTrace += "Special LDV benchmark detected. Setting loop unroll bar to 32.\n" loopUnrollBar = 32 else: heurTrace += "LDV benchmark detected. Setting loop unroll bar to 13.\n" loopUnrollBar = 13 staticLoopBound = 64 elif "standard_strcpy_false-valid-deref_ground_true-termination" in bpl or "960521-1_false-valid-free" in bpl or "960521-1_false-valid-deref" in bpl or "lockfree-3.3" in bpl or "list-ext_false-unreach-call_false-valid-deref" in bpl: heurTrace += "Memory safety benchmark detected. Setting loop unroll bar to 129.\n" loopUnrollBar = 129 elif "is_relaxed_prefix" in bpl: heurTrace += "Benchmark relax_* detected. Setting loop unroll bar to 15.\n" loopUnrollBar = 15 elif "id_o1000_false-unreach-call" in bpl: heurTrace += "Recursive benchmark detected. Setting loop unroll bar to 1024.\n" loopUnrollBar = 1024 elif "n.c24" in bpl or "array_false-unreach-call3" in bpl: heurTrace += "Loops benchmark detected. Setting loop unroll bar to 1024.\n" loopUnrollBar = 1024 elif "printf_false-unreach-call" in bpl or "echo_true-no-overflow" in bpl: heurTrace += "BusyBox benchmark detected. Setting loop unroll bar to 11.\n" loopUnrollBar = 11 elif args.memory_safety and "__main($i0" in bpl: heurTrace += "BusyBox memory safety benchmark detected. Setting loop unroll bar to 4.\n" loopUnrollBar = 4 elif args.integer_overflow and "__main($i0" in bpl: heurTrace += "BusyBox overflows benchmark detected. Setting loop unroll bar to 40.\n" loopUnrollBar = 40 elif args.integer_overflow and ("jain" in bpl or "TerminatorRec02" in bpl or "NonTerminationSimple" in bpl): heurTrace += "Infinite loop in overflow benchmark. Setting loop unroll bar to INT_MAX.\n" loopUnrollBar = 2**31 - 1 elif args.integer_overflow and ("(x != 0)" in csource or "(z > 0)" in csource or "(max > 0)" in csource or "(k < N)" in csource or "partial_sum" in csource): heurTrace += "Large overflow benchmark. Setting loop unroll bar to INT_MAX.\n" loopUnrollBar = 2**31 - 1 elif "i>>16" in csource: heurTrace += "Large array reach benchmark. Setting loop unroll bar to INT_MAX.\n" loopUnrollBar = 2**31 - 1 elif "whoop_poll_table" in csource: heurTrace += "Large concurrency benchmark. Setting loop unroll bar to INT_MAX.\n" loopUnrollBar = 2**31 - 1 if not "forall" in bpl: heurTrace += "No quantifiers detected. Setting z3 relevancy to 0.\n" corral_command += ["/bopt:z3opt:smt.relevancy=0"] if args.bit_precise: heurTrace += "--bit-precise flag passed - enabling bit vectors mode.\n" corral_command += ["/bopt:proverOpt:OPTIMIZE_FOR_BV=true"] corral_command += ["/bopt:boolControlVC"] if args.memory_safety: if args.prop_to_check == 'valid-deref': if "memleaks_test12_false-valid-free" in bpl: time_limit = 10 else: time_limit = 750 elif args.prop_to_check == 'valid-free': time_limit = 80 elif args.prop_to_check == 'memleak': time_limit = 50 else: time_limit = 880 command = list(corral_command) command += ["/timeLimit:%s" % time_limit] command += ["/v:1"] command += ["/maxStaticLoopBound:%d" % staticLoopBound] command += ["/recursionBound:65536"] command += ["/irreducibleLoopUnroll:12"] command += ["/trackAllVars"] verifier_output = smack.top.try_command(command, timeout=time_limit) result = smack.top.verification_result(verifier_output) if result == 'error' or result == 'invalid-deref' or result == 'invalid-free' or result == 'invalid-memtrack' or result == 'overflow': #normal inlining heurTrace += "Found a bug during normal inlining.\n" if not args.quiet: error = smack.top.error_trace(verifier_output, args) print error if args.memory_safety: heurTrace += (args.prop_to_check + "has errors\n") if args.prop_to_check == 'valid-free': if args.valid_deref_check_result != 'verified': force_timeout() elif args.prop_to_check == 'memleak': if args.valid_free_check_result == 'timeout': force_timeout() elif result == 'timeout': #normal inlining heurTrace += "Timed out during normal inlining.\n" heurTrace += "Determining result based on how far we unrolled.\n" # If we managed to unroll more than loopUnrollBar times, then return verified # First remove exhausted loop bounds generated during max static loop bound computation unrollMax = 0 if 'Verifying program while tracking' in verifier_output: verifier_output = re.sub(re.compile('.*Verifying program while tracking', re.DOTALL), 'Verifying program while tracking', verifier_output) it = re.finditer(r'Exhausted recursion bound of ([1-9]\d*)', verifier_output) for match in it: if int(match.group(1)) > unrollMax: unrollMax = int(match.group(1)) else: heurTrace += "Corral didn't even start verification.\n" if unrollMax >= loopUnrollBar: heurTrace += "Unrolling made it to a recursion bound of " heurTrace += str(unrollMax) + ".\n" heurTrace += "Reporting benchmark as 'verified'.\n" if args.execute and not args.pthread: heurTrace += "Hold on, let's see the execution result.\n" execution_result = run_binary(args) heurTrace += "Excecution result is " + execution_result + '\n' if execution_result != 'true': heurTrace += "Oops, execution result says {0}.\n".format(execution_result) if not args.quiet: print(heurTrace + "\n") sys.exit(smack.top.results(args)['unknown']) random_test_result = random_test(args, result) if random_test_result == 'false' or random_test_result == 'unknown': heurTrace += "Oops, random testing says {0}.\n".format(random_test_result) if not args.quiet: print(heurTrace + "\n") sys.exit(smack.top.results(args)['unknown']) if not args.quiet: print(heurTrace + "\n") if args.memory_safety: heurTrace += (args.prop_to_check + "is verified\n") if args.prop_to_check == 'valid-deref': args.valid_deref_check_result = 'verified' elif args.prop_to_check == 'valid-free': args.valid_free_check_result = 'verified' elif args.prop_to_check == 'memleak': if args.valid_deref_check_result == 'timeout': force_timeout() else: sys.exit(smack.top.results(args)[args.valid_deref_check_result]) verify_bpl_svcomp(args) else: write_error_file(args, 'verified', verifier_output) sys.exit(smack.top.results(args)['verified']) else: heurTrace += "Only unrolled " + str(unrollMax) + " times.\n" heurTrace += "Insufficient unrolls to consider 'verified'. " heurTrace += "Reporting 'timeout'.\n" if not args.quiet: print(heurTrace + "\n") sys.stdout.flush() if args.memory_safety: heurTrace += (args.prop_to_check + " times out\n") if args.prop_to_check == 'valid-deref': args.valid_deref_check_result = 'timeout' force_timeout() elif args.prop_to_check == 'valid-free': args.valid_free_check_result = 'timeout' elif args.prop_to_check == 'memleak': if args.valid_deref_check_result == 'timeout': force_timeout() else: sys.exit(smack.top.results(args)[args.valid_deref_check_result]) verify_bpl_svcomp(args) else: force_timeout() elif result == 'verified': #normal inlining heurTrace += "Normal inlining terminated and found no bugs.\n" else: #normal inlining heurTrace += "Normal inlining returned 'unknown'. See errors above.\n" if not args.quiet: print(heurTrace + "\n") if args.memory_safety and result == 'verified': heurTrace += (args.prop_to_check + " is verified\n") if args.prop_to_check == 'valid-deref': args.valid_deref_check_result = 'verified' elif args.prop_to_check == 'valid-free': args.valid_free_check_result = 'verified' elif args.prop_to_check == 'memleak': if args.valid_deref_check_result == 'timeout': force_timeout() else: sys.exit(smack.top.results(args)[args.valid_deref_check_result]) verify_bpl_svcomp(args) else: write_error_file(args, result, verifier_output) if args.only_check_memcleanup and result == 'invalid-memtrack': sys.exit('SMACK found an error: memory cleanup.') else: sys.exit(smack.top.results(args)[result])