예제 #1
0
def path_cover(ctxfn: FunctionInfo, options: AnalysisOptions,
               coverage_type: CoverageType) -> List[PathSummary]:
    fn, sig = ctxfn.callable()
    search_root = SinglePathNode(True)
    condition_start = time.monotonic()
    paths: List[PathSummary] = []
    for i in range(1, options.max_iterations):
        debug("Iteration ", i)
        itr_start = time.monotonic()
        if itr_start > condition_start + options.per_condition_timeout:
            debug(
                "Stopping due to --per_condition_timeout=",
                options.per_condition_timeout,
            )
            break
        space = StateSpace(
            execution_deadline=itr_start + options.per_path_timeout,
            model_check_timeout=options.per_path_timeout / 2,
            search_root=search_root,
        )
        with condition_parser(options.analysis_kind), Patched(
        ), COMPOSITE_TRACER, StateSpaceContext(space):
            summary = None
            try:
                summary = run_iteration(fn, sig, space)
                verification_status = VerificationStatus.CONFIRMED
            except UnexploredPath:
                verification_status = VerificationStatus.UNKNOWN
            debug("Verification status:", verification_status)
            top_analysis, exhausted = space.bubble_status(
                CallAnalysis(verification_status))
            debug("Path tree stats", search_root.stats())
            if summary:
                paths.append(summary)
            if exhausted:
                debug("Stopping due to code path exhaustion. (yay!)")
                break
    opcodes_found: Set[int] = set()
    selected: List[PathSummary] = []
    while paths:
        next_best = max(
            paths,
            key=lambda p: len(p.coverage.offsets_covered - opcodes_found))
        cur_offsets = next_best.coverage.offsets_covered
        if coverage_type == CoverageType.OPCODE:
            if len(cur_offsets - opcodes_found) == 0:
                break
        selected.append(next_best)
        opcodes_found |= cur_offsets
        paths = [p for p in paths if p is not next_best]
    return selected
 def symbolic_run(
     self,
     fn: Callable[[StateSpace, Dict[str, object]], object],
     typed_args: Dict[str, type],
 ) -> Tuple[object,  # return value
            Optional[Dict[str, object]],  # arguments after execution
            Optional[BaseException],  # exception thrown, if any
            StateSpace, ]:
     search_root = SinglePathNode(True)
     with COMPOSITE_TRACER, Patched():
         for itr in range(1, 200):
             debug("iteration", itr)
             space = StateSpace(time.monotonic() + 10.0,
                                1.0,
                                search_root=search_root)
             symbolic_args = {}
             try:
                 with StateSpaceContext(space):
                     symbolic_args = {
                         name: proxy_for_type(typ, name)
                         for name, typ in typed_args.items()
                     }
                     ret = fn(space, symbolic_args)
                     ret = (deep_realize(ret), symbolic_args, None, space)
                     space.check_deferred_assumptions()
                     return ret
             except IgnoreAttempt as e:
                 debug("ignore iteration attempt: ", str(e))
                 pass
             except BaseException as e:
                 debug(traceback.format_exc())
                 return (None, symbolic_args, e, space)
             top_analysis, space_exhausted = space.bubble_status(
                 CallAnalysis())
             if space_exhausted:
                 return (
                     None,
                     symbolic_args,
                     CrosshairInternal(f"exhausted after {itr} iterations"),
                     space,
                 )
     return (
         None,
         None,
         CrosshairInternal(
             "Unable to find a successful symbolic execution"),
         space,
     )
예제 #3
0
def diff_behavior_with_signature(
    fn1: Callable, fn2: Callable, sig: inspect.Signature, options: AnalysisOptions
) -> Iterable[BehaviorDiff]:
    search_root = SinglePathNode(True)
    condition_start = time.monotonic()
    for i in range(1, options.max_iterations):
        debug("Iteration ", i)
        itr_start = time.monotonic()
        if itr_start > condition_start + options.per_condition_timeout:
            debug(
                "Stopping due to --per_condition_timeout=",
                options.per_condition_timeout,
            )
            return
        options.incr("num_paths")
        space = StateSpace(
            execution_deadline=itr_start + options.per_path_timeout,
            model_check_timeout=options.per_path_timeout / 2,
            search_root=search_root,
        )
        with StateSpaceContext(space):
            output = None
            try:
                (verification_status, output) = run_iteration(fn1, fn2, sig, space)
            except UnexploredPath:
                verification_status = VerificationStatus.UNKNOWN
            debug("Verification status:", verification_status)
            top_analysis, space_exhausted = space.bubble_status(
                CallAnalysis(verification_status)
            )
            if (
                top_analysis
                and top_analysis.verification_status == VerificationStatus.CONFIRMED
            ):
                debug("Stopping due to code path exhaustion. (yay!)")
                options.incr("exhaustion")
                break
            if output:
                yield output