def update_patch_list(result_list, patch_list, path_condition, assertion): updated_patch_list = [] if len(result_list) != len(patch_list): recover_list = recover_patch_list(result_list, patch_list, path_condition, assertion) result_list = result_list + recover_list for result in result_list: refined_space, index, patch_score, is_under_approx, is_over_approx = result patch = patch_list[index] patch_constraint = app.generator.generate_formula_from_patch(patch) patch_constraint_str = patch_constraint.serialize() patch_index = utilities.get_hash(patch_constraint_str) values.LIST_PATCH_SCORE[patch_index] += patch_score if is_under_approx is not None: current_state = values.LIST_PATCH_UNDERAPPROX_CHECK[patch_index] final_state = is_under_approx values.LIST_PATCH_UNDERAPPROX_CHECK[patch_index] = final_state if is_over_approx is not None: current_state = values.LIST_PATCH_OVERAPPROX_CHECK[patch_index] final_state = is_over_approx values.LIST_PATCH_OVERAPPROX_CHECK[patch_index] = final_state if values.DEFAULT_REFINE_METHOD == values.OPTIONS_REFINE_METHOD[3]: updated_patch_list.append(patch) else: if refined_space: values.LIST_PATCH_SPACE[patch_index] = refined_space updated_patch_list.append(patch) else: # emitter.debug("Removing Patch", patch_list[index]) emitter.emit_patch(patch, message="\t\tRemoving Patch: ") return updated_patch_list
def print_patch_list(patch_list): template_count = 0 emitter.sub_title("List of Top " + str(values.DEFAULT_PATCH_RANK_LIMIT) + " Correct Patches") if not patch_list: emitter.warning("\t[warning] unable to generate any patch") return for patch in patch_list: template_count = template_count + 1 emitter.sub_sub_title("Patch #" + str(template_count)) emitter.emit_patch(patch, message="\t\t") patch_formula = app.generator.generate_formula_from_patch(patch) patch_formula_str = patch_formula.serialize() patch_index = utilities.get_hash(patch_formula_str) patch_score = values.LIST_PATCH_SCORE[patch_index] concrete_patch_count = 1 if values.DEFAULT_PATCH_TYPE == values.OPTIONS_PATCH_TYPE[1]: patch_space = values.LIST_PATCH_SPACE[patch_index] partition_count = 0 for partition in patch_space: partition_count = partition_count + 1 emitter.highlight("\t\tPartition: " + str(partition_count)) for constant_name in partition: emitter.highlight("\t\t\tConstant: " + constant_name) constant_info = partition[constant_name] lower_bound = str(constant_info['lower-bound']) upper_bound = str(constant_info['upper-bound']) emitter.highlight("\t\t\tRange: " + lower_bound + " <= " + constant_name + " <= " + upper_bound) dimension = len( range(int(lower_bound), int(upper_bound) + 1)) emitter.highlight("\t\t\tDimension: " + str(dimension)) concrete_patch_count = utilities.count_concrete_patches_per_template( patch) emitter.highlight("\t\tPatch Count: " + str(concrete_patch_count)) emitter.highlight("\t\tPath Coverage: " + str(patch_score)) emitter.highlight( "\t\tIs Under-approximating: " + str(values.LIST_PATCH_UNDERAPPROX_CHECK[patch_index])) emitter.highlight("\t\tIs Over-approximating: " + str(values.LIST_PATCH_OVERAPPROX_CHECK[patch_index])) if template_count == values.DEFAULT_PATCH_RANK_LIMIT: break
def select_patch_constraint_for_input(patch_list, selected_new_path): # relationship = extractor.extract_var_relationship(var_expr_map) # relationship = TRUE # selected_new_path = And(selected_new_path, relationship) result_list = parallel.validate_input_generation(patch_list, selected_new_path) sorted_result_list = sorted(result_list, key=operator.itemgetter(1)) filtered_patch_list = list() for result in sorted_result_list: is_valid, index = result selected_patch = patch_list[index] if is_valid: filtered_patch_list.append(selected_patch) if not filtered_patch_list: # emitter.note("\t\tCount paths explored: " + str(len(list_path_explored))) # emitter.note("\t\tCount paths remaining: " + str(len(list_path_detected))) return None if values.DEFAULT_SELECTION_STRATEGY == "deterministic": selected_patch = filtered_patch_list[0] else: selected_patch = random.choice(filtered_patch_list) emitter.emit_patch(selected_patch, message="\t\tSelected patch: ") patch_formula = app.generator.generate_formula_from_patch(selected_patch) patch_formula_extended = generator.generate_extended_patch_formula( patch_formula, selected_new_path) patch_space_constraint = patch_formula_extended if values.DEFAULT_PATCH_TYPE == values.OPTIONS_PATCH_TYPE[1]: patch_formula_str = str(patch_formula.serialize()) patch_index = utilities.get_hash(patch_formula_str) patch_space = values.LIST_PATCH_SPACE[patch_index] parameter_constraint = smt2.generate_constraint_for_patch_space( patch_space) if parameter_constraint: patch_space_constraint = And(patch_formula_extended, parameter_constraint) # add patch constraint and user-input->prog-var relationship return patch_space_constraint
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