Search in sources :

Example 1 with ExceptionDest

use of soot.toolkits.graph.ExceptionalGraph.ExceptionDest in project soot by Sable.

the class CFGToDotGraph method drawCFG.

/**
 * Create a <code>DotGraph</code> whose nodes and edges depict the
 * control flow in a <code>ExceptionalGraph</code>, with
 * distinguished edges for exceptional control flow.
 *
 * @param graph the control flow graph
 *
 * @return a visualization of <code>graph</code>.
 */
public <N> DotGraph drawCFG(ExceptionalGraph<N> graph) {
    Body body = graph.getBody();
    DotGraph canvas = initDotGraph(body);
    DotNamer namer = new DotNamer((int) (graph.size() / 0.7f), 0.7f);
    NodeComparator nodeComparator = new NodeComparator(namer);
    // comparisons between graphs of a given method.
    for (Iterator<N> nodesIt = graph.iterator(); nodesIt.hasNext(); ) {
        namer.getName(nodesIt.next());
    }
    for (Iterator<N> nodesIt = graph.iterator(); nodesIt.hasNext(); ) {
        N node = nodesIt.next();
        canvas.drawNode(namer.getName(node));
        for (Iterator<N> succsIt = sortedIterator(graph.getUnexceptionalSuccsOf(node), nodeComparator); succsIt.hasNext(); ) {
            N succ = succsIt.next();
            DotGraphEdge edge = canvas.drawEdge(namer.getName(node), namer.getName(succ));
            edge.setAttribute(unexceptionalControlFlowAttr);
        }
        for (Iterator<N> succsIt = sortedIterator(graph.getExceptionalSuccsOf(node), nodeComparator); succsIt.hasNext(); ) {
            N succ = succsIt.next();
            DotGraphEdge edge = canvas.drawEdge(namer.getName(node), namer.getName(succ));
            edge.setAttribute(exceptionalControlFlowAttr);
        }
        if (showExceptions) {
            for (Iterator<ExceptionDest<N>> destsIt = sortedIterator(graph.getExceptionDests(node), new ExceptionDestComparator(namer)); destsIt.hasNext(); ) {
                ExceptionDest<N> dest = destsIt.next();
                Object handlerStart = dest.getHandlerNode();
                if (handlerStart == null) {
                    // Giving each escaping exception its own, invisible
                    // exceptional exit node produces a less cluttered
                    // graph.
                    handlerStart = new Object() {

                        public String toString() {
                            return "Esc";
                        }
                    };
                    DotGraphNode escapeNode = canvas.drawNode(namer.getName(handlerStart));
                    escapeNode.setStyle(DotGraphConstants.NODE_STYLE_INVISIBLE);
                }
                DotGraphEdge edge = canvas.drawEdge(namer.getName(node), namer.getName(handlerStart));
                edge.setAttribute(exceptionEdgeAttr);
                edge.setLabel(formatThrowableSet(dest.getThrowables()));
            }
        }
    }
    setStyle(graph.getHeads(), canvas, namer, DotGraphConstants.NODE_STYLE_FILLED, headAttr);
    setStyle(graph.getTails(), canvas, namer, DotGraphConstants.NODE_STYLE_FILLED, tailAttr);
    if (!isBrief) {
        formatNodeText(graph.getBody(), canvas, namer);
    }
    return canvas;
}
Also used : ExceptionDest(soot.toolkits.graph.ExceptionalGraph.ExceptionDest) DotGraphEdge(soot.util.dot.DotGraphEdge) DotGraph(soot.util.dot.DotGraph) DotGraphNode(soot.util.dot.DotGraphNode)

Example 2 with ExceptionDest

use of soot.toolkits.graph.ExceptionalGraph.ExceptionDest in project soot by Sable.

the class TrapMinimizer method internalTransform.

@Override
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
    // If we have less then two traps, there's nothing to do here
    if (b.getTraps().size() == 0)
        return;
    ExceptionalUnitGraph eug = new ExceptionalUnitGraph(b, DalvikThrowAnalysis.v(), Options.v().omit_excepting_unit_edges());
    Set<Unit> unitsWithMonitor = getUnitsWithMonitor(eug);
    Map<Trap, List<Trap>> replaceTrapBy = new HashMap<Trap, List<Trap>>(b.getTraps().size());
    boolean updateTrap = false;
    for (Trap tr : b.getTraps()) {
        // will contain the new
        List<Trap> newTraps = new ArrayList<Trap>();
        // traps
        // points to the first unit
        Unit firstTrapStmt = tr.getBeginUnit();
        // in the trap
        // true if there is an edge from the
        boolean goesToHandler = false;
        // unit to the handler of the
        // current trap
        updateTrap = false;
        for (Unit u = tr.getBeginUnit(); u != tr.getEndUnit(); u = b.getUnits().getSuccOf(u)) {
            if (goesToHandler) {
                goesToHandler = false;
            } else {
                // if the previous unit has no exceptional edge to the
                // handler,
                // update firstTrapStmt to point to the current unit
                firstTrapStmt = u;
            }
            // active monitor, we need to keep the block
            if (tr.getException().getName().equals("java.lang.Throwable") && unitsWithMonitor.contains(u))
                goesToHandler = true;
            // handler
            if (!goesToHandler)
                if (DalvikThrowAnalysis.v().mightThrow(u).catchableAs(tr.getException().getType())) {
                    // to be inside the new minimized catch block.
                    for (ExceptionDest<Unit> ed : eug.getExceptionDests(u)) {
                        if (ed.getTrap() == tr) {
                            goesToHandler = true;
                            break;
                        }
                    }
                }
            if (!goesToHandler) {
                // if the current unit does not have an edge to the current
                // trap's handler,
                // add a new trap starting at firstTrapStmt ending at the
                // unit before the
                // current unit 'u'.
                updateTrap = true;
                if (// do not add an empty trap, but set
                firstTrapStmt == u)
                    // updateTrap to true
                    continue;
                Trap t = Jimple.v().newTrap(tr.getException(), firstTrapStmt, u, tr.getHandlerUnit());
                newTraps.add(t);
            } else {
                // next unit is outside the current trap.
                if (b.getUnits().getSuccOf(u) == tr.getEndUnit() && updateTrap) {
                    Trap t = Jimple.v().newTrap(tr.getException(), firstTrapStmt, tr.getEndUnit(), tr.getHandlerUnit());
                    newTraps.add(t);
                }
            }
        }
        // cannot throw any exceptions)
        if (updateTrap) {
            replaceTrapBy.put(tr, newTraps);
        }
    }
    // replace traps where necessary
    for (Trap k : replaceTrapBy.keySet()) {
        // we must keep
        b.getTraps().insertAfter(replaceTrapBy.get(k), k);
        // the order
        b.getTraps().remove(k);
    }
}
Also used : ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) ExceptionDest(soot.toolkits.graph.ExceptionalGraph.ExceptionDest) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Trap(soot.Trap) ArrayList(java.util.ArrayList) List(java.util.List) Unit(soot.Unit)

Aggregations

ExceptionDest (soot.toolkits.graph.ExceptionalGraph.ExceptionDest)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Trap (soot.Trap)1 Unit (soot.Unit)1 ExceptionalUnitGraph (soot.toolkits.graph.ExceptionalUnitGraph)1 DotGraph (soot.util.dot.DotGraph)1 DotGraphEdge (soot.util.dot.DotGraphEdge)1 DotGraphNode (soot.util.dot.DotGraphNode)1