def refine_input_partition(path_condition, assertion, input_partition, is_multi_dimension): input_constraints = generator.generate_constraint_for_input_partition(input_partition) path_constraints = And(path_condition, input_constraints) is_exist_check = And(path_constraints, Not(assertion)) is_always_check = And(path_constraints, assertion) refined_partition_list = [] if is_sat(is_always_check): if is_sat(is_exist_check): concrete_count = 1 for parameter in input_partition: dimension = len( range(input_partition[parameter]['lower-bound'], input_partition[parameter]['upper-bound'] + 1)) concrete_count = concrete_count * dimension if concrete_count > 1: break if concrete_count == 1: return refined_partition_list partition_model = generator.generate_model(is_exist_check) partition_model, is_multi_dimension = extractor.extract_input_list(partition_model) partition_list = generator.generate_partition_for_input_space(partition_model, input_partition, is_multi_dimension) for partition in partition_list: if refined_partition_list: refined_partition_list = refined_partition_list + refine_input_partition(path_condition, assertion, partition, is_multi_dimension) else: refined_partition_list = refine_input_partition(path_condition, assertion, partition, is_multi_dimension) else: refined_partition_list.append(input_partition) return refined_partition_list
def partition_input_space(path_condition, assertion): global pool, result_list result_list = [] is_exist = And(path_condition, Not(assertion)) is_always = And(path_condition, assertion) input_space = generator.generate_input_space(path_condition) if oracle.is_loc_in_trace(values.CONF_LOC_BUG): if is_sat(is_exist): emitter.normal("\tpartitioning input space") partition_model = generator.generate_model(is_exist) partition_model, is_multi_dimension = extractor.extract_input_list( partition_model) partition_list = generator.generate_partition_for_input_space( partition_model, input_space, is_multi_dimension) if values.DEFAULT_OPERATION_MODE in ["sequential"]: for partition in partition_list: # emitter.emit_patch(patch, message="\tabstract patch: ") result_list.append( refine.refine_input_partition(path_condition, assertion, partition, is_multi_dimension)) else: emitter.normal("\t\tstarting parallel computing") pool = mp.Pool(mp.cpu_count(), initializer=mute) for partition in partition_list: pool.apply_async(refine.refine_input_partition, args=(path_condition, assertion, partition, is_multi_dimension), callback=collect_result) pool.close() emitter.normal("\t\twaiting for thread completion") pool.join() filtered_list = list() for partition in result_list: if not partition: continue if isinstance(partition, list): for sub_partition in partition: filtered_list.append(sub_partition) else: filtered_list.append(partition) result_list = filtered_list return result_list
def refine_patch_partition(path_constraint, patch_partition, p_specification, is_multi_dimension): parameter_constraint = smt2.generate_constraint_for_patch_partition(patch_partition) path_feasibility = And(path_constraint, And(parameter_constraint, p_specification)) refined_partition_list = [] if is_sat(path_feasibility): concrete_count = 1 for parameter in patch_partition: dimension = len(range(patch_partition[parameter]['lower-bound'], patch_partition[parameter]['upper-bound'] + 1)) concrete_count = concrete_count * dimension if concrete_count > 1: break if concrete_count == 1: return refined_partition_list partition_model = generator.generate_model(path_feasibility) partition_model, is_multi_dimension = extractor.extract_parameter_list(partition_model) partition_list = generator.generate_partition_for_patch_space(partition_model, patch_partition, is_multi_dimension) for partition in partition_list: if refined_partition_list: refined_partition_list = refined_partition_list + refine_patch_partition(path_constraint, partition, p_specification, is_multi_dimension) else: refined_partition_list = refine_patch_partition(path_constraint, partition, p_specification, is_multi_dimension) else: refined_partition_list = [patch_partition] return refined_partition_list
def run_cegis(program_path, project_path, patch_list): test_output_list = values.LIST_TEST_OUTPUT test_template = reader.collect_specification(test_output_list[0]) binary_dir_path = "/".join(program_path.split("/")[:-1]) time_check = time.time() assertion, largest_path_condition = concolic.run_concolic_exploration( program_path, patch_list) duration = (time.time() - time_check) / 60 values.TIME_TO_EXPLORE = duration emitter.normal("\tcombining explored program paths") if not assertion: patch = patch_list[0] emitter.emit_patch(patch, message="\tfinal patch: ") return program_specification = generator.generate_program_specification( binary_dir_path) complete_specification = And(Not(assertion), program_specification) emitter.normal("\tcomputed the program specification formula") emitter.sub_title("Evaluating Patch Pool") iteration = 0 output_dir = definitions.DIRECTORY_OUTPUT counter_example_list = [] time_check = time.time() values.CONF_TIME_CHECK = None satisfied = utilities.check_budget(values.DEFAULT_TIMEOUT_CEGIS_REFINE) patch_generator = generator.generate_patch(project_path, counter_example_list) count_throw = 0 while not satisfied: iteration = iteration + 1 values.ITERATION_NO = iteration emitter.sub_sub_title("Iteration: " + str(iteration)) patch = next(patch_generator, None) if not patch: emitter.error("[error] cannot generate a patch") patch_formula = app.generator.generate_formula_from_patch(patch) emitter.emit_patch(patch, message="\tgenerated patch: ") patch_formula_extended = generator.generate_extended_patch_formula( patch_formula, largest_path_condition) violation_check = And(complete_specification, patch_formula_extended) if is_sat(violation_check): model = generator.generate_model(violation_check) # print(model) arg_list = values.ARGUMENT_LIST poc_path = values.CONF_PATH_POC values.FILE_POC_GEN = definitions.DIRECTORY_OUTPUT + "/violation-" + str( values.ITERATION_NO) gen_path = values.FILE_POC_GEN input_arg_list, input_var_list = generator.generate_new_input( violation_check, arg_list, poc_path, gen_path) klee_out_dir = output_dir + "/klee-output-" + str(iteration) klee_test_file = output_dir + "/klee-test-" + str(iteration) exit_code = concolic.run_concrete_execution( program_path + ".bc", input_arg_list, True, klee_out_dir) # assert exit_code == 0 emitter.normal("\t\tgenerating new assertion") test_assertion, count_obs = generator.generate_assertion( test_template, klee_out_dir) write_smtlib(test_assertion, klee_test_file) counter_example_list.append((klee_test_file, klee_out_dir)) emitter.highlight("\t\tnew counter-example added") patch = None emitter.highlight("\t\tremoving current patch") count_throw = count_throw + 1 else: klee_test_file = output_dir + "/klee-test-FINAL" # print(to_smtlib(violation_check, False)) write_smtlib(violation_check, klee_test_file) break satisfied = utilities.check_budget(values.DEFAULT_TIMEOUT_CEGIS_REFINE) if satisfied: emitter.warning("\t[warning] ending due to timeout of " + str(values.DEFAULT_TIMEOUT_CEGIS_REFINE) + " minutes") duration = (time.time() - time_check) / 60 values.TIME_TO_REDUCE = duration # patch_list = [patch] # definitions.FILE_PATCH_SET = definitions.DIRECTORY_OUTPUT + "/patch-set-cegis" # writer.write_patch_set(patch_list, definitions.FILE_PATCH_SET) # patch = next(patch_generator, None) # while patch is not None: # patch_formula = app.generator.generate_formula_from_patch(patch) # patch_formula_extended = generator.generate_extended_patch_formula(patch_formula, largest_path_condition) # violation_check = And(complete_specification, patch_formula_extended) # if is_unsat(violation_check): # count_final = count_final + 1 # patch = next(patch_generator, None) emitter.emit_patch(patch, message="\tfinal patch: ") values.COUNT_PATCH_END = values.COUNT_PATCH_START - count_throw