Пример #1
0
def build_resulting_graph(file_name, cfg, dead_blocks):
    dead_nodes = frozenset(node for block in dead_blocks
                           for node in block.nodes)

    def dead_label(orig):
        return {'dead': True} if orig in dead_nodes else {}

    new_node_map = {
        node: Digraph.Node(node.name, ___orig=node, **dead_label(node))
        for node in cfg.nodes
    }

    res_graph = Digraph([new_node_map[n] for n in cfg.nodes], [
        Digraph.Edge(new_node_map[e.frm], new_node_map[e.to])
        for e in cfg.edges
    ])

    def print_orig(orig):
        if orig.data.node is not None:
            return ('<i>{}</i>'.format(html_render_node(orig.data.node)), )
        return ()

    def print_dead_code(value):
        return ('<font color="{}">{}</font>'.format('red', 'Dead node'), )

    with open(file_name, 'w') as f:
        f.write(
            dot_printer.gen_dot(res_graph, [
                dot_printer.DataPrinter('___orig', print_orig),
                dot_printer.DataPrinter("dead", print_dead_code)
            ]))
Пример #2
0
    def visit_program(self, prgm):
        self.nodes = []
        self.edges = []
        self.jumps = []
        self.labels = {}

        start = self.build_node("start")
        self.visit_stmts(prgm.stmts, start)

        # Generate jump edges
        for node, label in self.jumps:
            self.edges.extend([
                Digraph.Edge(node, edge.to)
                for edge in self.edges
                if edge.frm == self.labels[label]
            ])

        # Compute reachable nodes
        reachables = set()
        self.compute_reachable_nodes(start, reachables)

        # Remove all nodes and edges that are not reachable
        self.nodes = [n for n in self.nodes if n in reachables]
        self.edges = [e for e in self.edges if e.frm in reachables]

        return Digraph([start] + self.nodes, self.edges)
Пример #3
0
    def visit_program(self, prgm):
        self.nodes = []
        self.edges = []
        self.jumps = []
        self.labels = {}

        start = self.build_node("start")
        self.visit_stmts(prgm.stmts, start)

        # Generate jump edges
        for node, label in self.jumps:
            self.edges.extend([
                Digraph.Edge(node, edge.to) for edge in self.edges
                if edge.frm == self.labels[label]
            ])

        # Post process the CFG to find infer widening points and compute
        # the set of reachable nodes.
        visit_results = self.post_process_cfg(start)

        # Remove all nodes and edges that are not reachable
        self.nodes = [
            n for n in self.nodes if visit_results[n] != CFGBuilder.NOT_VISITED
        ]
        self.edges = [
            e for e in self.edges
            if visit_results[e.frm] != CFGBuilder.NOT_VISITED
        ]

        return Digraph([start] + self.nodes, self.edges)
Пример #4
0
def build_resulting_graph(file_name, cfg, null_derefs):
    def trace_id(trace):
        return str(trace)

    paths = defaultdict(list)

    for trace, derefed, precise in null_derefs:
        for node in trace:
            paths[node].append((trace, derefed, precise))

    new_node_map = {
        node: Digraph.Node(
            node.name,
            ___orig=node,
            **{
                trace_id(trace): (derefed, precise)
                for trace, derefed, precise in paths[node]
            }
        )
        for node in cfg.nodes
    }

    res_graph = Digraph(
        [new_node_map[n]
         for n in cfg.nodes],

        [Digraph.Edge(new_node_map[e.frm], new_node_map[e.to])
         for e in cfg.edges]
    )

    def print_orig(orig):
        if orig.data.node is not None:
            return (
                '<i>{}</i>'.format(html_render_node(orig.data.node)),
            )
        return ()

    def print_path_to_null_deref(value):
        derefed, precise = value
        qualifier = "" if precise else "potential "
        res_str = "path to {}null dereference of {}".format(
            qualifier, html_render_node(derefed)
        )
        return (
            '<font color="{}">{}</font>'.format('red', res_str),
        )

    with open(file_name, 'w') as f:
        f.write(dot_printer.gen_dot(res_graph, [
            dot_printer.DataPrinter('___orig', print_orig)
        ] + [
            dot_printer.DataPrinter(
                trace_id(trace),
                print_path_to_null_deref
            )
            for trace, _, _ in null_derefs
        ]))
Пример #5
0
def _build_resulting_graph(file_name, cfg, results, trace_domain, model):
    paths = defaultdict(list)

    var_set = {
        v
        for node, state in results.iteritems()
        for trace, values in state.iteritems() for v, _ in values.iteritems()
    }

    for node, state in results.iteritems():
        for trace, values in state.iteritems():
            paths[frozenset(trace)].append(
                Digraph.Node(node.name,
                             ___orig=node,
                             **{
                                 v.name: value
                                 for v, value in values.iteritems()
                                 if not SyntheticVariable.is_purpose_of(v)
                             }))

    edges = []
    for trace, nodes in paths.iteritems():
        for node in nodes:
            predecessors = [
                n for t, ns in paths.iteritems() for n in ns
                if trace_domain.le(t, trace)
                if n.data.___orig in cfg.ancestors(node.data.___orig)
            ]

            for pred in predecessors:
                edges.append(Digraph.Edge(pred, node))

    res_graph = Digraph([n for _, nodes in paths.iteritems() for n in nodes],
                        edges)

    def print_orig(orig):
        if orig.data.node is not None:
            return ('<i>{}</i>'.format(_html_render_node(orig.data.node)), )
        return ()

    def print_result_builder(v):
        return lambda value: ("{} &isin;".format(v.name),
                              escape(model[v].domain.str(value)))

    with open(file_name, 'w') as f:
        f.write(
            dot_printer.gen_dot(
                res_graph, [dot_printer.DataPrinter('___orig', print_orig)] + [
                    dot_printer.DataPrinter(v.name, print_result_builder(v))
                    for v in var_set
                ]))
Пример #6
0
def build_resulting_graph(file_name, cfg, infeasibles):
    def trace_id(trace):
        return str(trace)

    paths = defaultdict(list)

    for trace, derefed, precise in infeasibles:
        for node in trace:
            paths[node].append((trace, derefed, precise))

    new_node_map = {
        node: Digraph.Node(node.name,
                           ___orig=node,
                           **{
                               trace_id(trace): (derefed, precise)
                               for trace, derefed, precise in paths[node]
                           })
        for node in cfg.nodes
    }

    res_graph = Digraph([new_node_map[n] for n in cfg.nodes], [
        Digraph.Edge(new_node_map[e.frm], new_node_map[e.to])
        for e in cfg.edges
    ])

    def print_orig(orig):
        if orig.data.node is not None:
            return ('<i>{}</i>'.format(html_render_node(orig.data.node)), )
        return ()

    def print_path_to_infeasible_access(value):
        purpose, precise = value
        prefix = html_render_node(purpose.accessed_expr)
        qualifier = "" if precise else "potential "
        res_str = ("path to {}infeasible access {}.{} due to invalid "
                   "condition on discriminant {}.{}").format(
                       qualifier, prefix, escape(purpose.field_name), prefix,
                       escape(purpose.discr_name))
        return ('<font color="{}">{}</font>'.format('red', res_str), )

    with open(file_name, 'w') as f:
        f.write(
            dot_printer.gen_dot(
                res_graph, [dot_printer.DataPrinter('___orig', print_orig)] + [
                    dot_printer.DataPrinter(trace_id(trace),
                                            print_path_to_infeasible_access)
                    for trace, _, _ in infeasibles
                ]))
Пример #7
0
def export_schedule(schedule, export_path):
    """
    Exports the given schedule as a dot graph. Each horizontally aligned
    elements can be ran in parallel.

    :param lalcheck.tools.scheduler.Schedule schedule: The schedule to export.
    :param str export_path: The path to the dot file to write. The .dot
        extension is appended here.
    """
    nice_colors = [
        '#093145', '#107896', '#829356', '#3C6478', '#43ABC9', '#B5C689',
        '#BCA136', '#C2571A', '#9A2617', '#F26D21', '#C02F1D', '#F58B4C',
        '#CD594A'
    ]

    def var_printer(var):
        name = str(var)
        color = nice_colors[hash(name) % len(nice_colors)]

        def colored(x):
            return '<font color="{}">{}</font>'.format(color, x)

        def printer(x):
            return ('<i>{}</i>'.format(colored(name)), colored(x))

        return printer

    tasks = frozenset(task for batch in schedule.batches for task in batch)

    varset = frozenset(var for task in tasks for var in vars(task).keys())

    task_to_node = {
        task: Digraph.Node(task.__class__.__name__, **vars(task))
        for task in tasks
    }

    edges = [
        Digraph.Edge(task_to_node[a], task_to_node[b]) for a in tasks
        for b in tasks if len(
            frozenset(a.provides().values())
            & frozenset(b.requires().values())) > 0
    ]

    digraph = Digraph(task_to_node.values(), edges)
    dot = gen_dot(digraph,
                  [DataPrinter(var, var_printer(var)) for var in varset])
    with open("{}.dot".format(export_path), 'w') as export_file:
        export_file.write(dot)
Пример #8
0
 def register_and_link(self, froms, new_node):
     self.nodes.append(new_node)
     for f in froms:
         if f is not None:
             self.edges.append(Digraph.Edge(f, new_node))