Extended exceptionan anlysis with exception filter.

This commit is contained in:
Stephan Gocht 2015-11-30 23:02:40 +01:00
parent 77b1ed71c7
commit bed18b792c
10 changed files with 253 additions and 37 deletions

View File

@ -19,28 +19,39 @@ import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural.InterproceduralExceptionFilter;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.graph.Graph;
import com.ibm.wala.util.graph.impl.InvertedGraph;
import com.ibm.wala.util.graph.impl.SelfLoopAddedGraph;
public class ExceptionAnalysis {
public class ExceptionAnalysis {
private BitVectorSolver<CGNode> solver;
private ExceptionToBitvectorTransformer transformer;
public ExceptionAnalysis(CallGraph callgraph, PointerAnalysis<InstanceKey> pointerAnalysis, ClassHierarchy cha){
IntraproceduralResult intraResult = new IntraproceduralResult(callgraph, pointerAnalysis, cha);
transformer = new ExceptionToBitvectorTransformer(intraResult.getExceptions());
ExceptionTransferFunctionProvider transferFunctionProvider = new ExceptionTransferFunctionProvider(intraResult, callgraph, transformer);
public ExceptionAnalysis(CallGraph callgraph, PointerAnalysis<InstanceKey> pointerAnalysis, ClassHierarchy cha) {
this(callgraph, pointerAnalysis, cha, null);
}
public ExceptionAnalysis(CallGraph callgraph, PointerAnalysis<InstanceKey> pointerAnalysis, ClassHierarchy cha,
InterproceduralExceptionFilter<SSAInstruction> filter) {
IntraproceduralResult intraResult = new IntraproceduralResult(callgraph, pointerAnalysis, cha, filter);
transformer = new ExceptionToBitvectorTransformer(intraResult.getExceptions());
ExceptionTransferFunctionProvider transferFunctionProvider = new ExceptionTransferFunctionProvider(intraResult, callgraph,
transformer);
Graph<CGNode> graph = new SelfLoopAddedGraph<>(new InvertedGraph<CGNode>(callgraph));
BitVectorFramework<CGNode, TypeReference> problem = new BitVectorFramework<>(graph, transferFunctionProvider, transformer.getValues());
BitVectorFramework<CGNode, TypeReference> problem = new BitVectorFramework<>(graph, transferFunctionProvider,
transformer.getValues());
solver = new ExceptionFlowSolver(problem, intraResult, transformer);
solver.initForFirstSolve();
}
public void solve() {
try {
solver.solve(null);
} catch (CancelException e) {
@ -48,8 +59,8 @@ public class ExceptionAnalysis {
e.printStackTrace();
}
}
public Set<TypeReference> getCGNodeExceptions(CGNode node){
public Set<TypeReference> getCGNodeExceptions(CGNode node) {
BitVectorVariable nodeResult = solver.getIn(node);
if (nodeResult != null) {
return transformer.computeExceptions(nodeResult);

View File

@ -85,14 +85,12 @@ public class ExceptionTransferFunctionProvider implements ITransferFunctionProvi
Iterator<CallSiteReference> callsites = cg.getPossibleSites(src, dst);
BitVector filtered = new BitVector(transformer.getValues().getSize());
if (callsites.hasNext()) {
System.out.println(src.getMethod().toString() + " -> " + dst.getMethod().toString());
if (callsites.hasNext()) {
CallSiteReference callsite = callsites.next();
filtered = transformer.computeBitVector(intraResult.getFilteredExceptions(src, callsite));
filtered = transformer.computeBitVector(intraResult.getCaughtExceptions(src, callsite));
while (callsites.hasNext()) {
callsite = callsites.next();
BitVector bv = transformer.computeBitVector(intraResult.getFilteredExceptions(src, callsite));
BitVector bv = transformer.computeBitVector(intraResult.getCaughtExceptions(src, callsite));
filtered.and(bv);
}

View File

@ -10,6 +10,7 @@
*******************************************************************************/
package com.ibm.wala.analysis.exceptionanalysis;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@ -21,12 +22,13 @@ import java.util.Set;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
import com.ibm.wala.ipa.cfg.exceptionpruning.FilteredException;
import com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural.InterproceduralExceptionFilter;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
@ -44,11 +46,14 @@ public class IntraproceduralResult {
private CallGraph callGraph;
private PointerAnalysis<InstanceKey> pointerAnalysis;
private ClassHierarchy classHierachy;
private InterproceduralExceptionFilter<SSAInstruction> filter;
public IntraproceduralResult(CallGraph cg, PointerAnalysis<InstanceKey> pointerAnalysis, ClassHierarchy cha) {
public IntraproceduralResult(CallGraph cg, PointerAnalysis<InstanceKey> pointerAnalysis, ClassHierarchy cha,
InterproceduralExceptionFilter<SSAInstruction> filter) {
this.callGraph = cg;
this.pointerAnalysis = pointerAnalysis;
this.classHierachy = cha;
this.filter = filter;
intraproceduralExceptions = new HashMap<>();
exceptions = new HashSet<>();
compute();
@ -64,14 +69,13 @@ public class IntraproceduralResult {
for (ISSABasicBlock block : ir.getControlFlowGraph()) {
SSAInstruction throwingInstruction = getThrowingInstruction(block);
if (throwingInstruction != null) {
Set<TypeReference> caughtExceptions = collectCaughtExceptions(node, block);
Set<TypeReference> thrownExceptions = collectThrownExceptions(node, throwingInstruction);
Set<TypeReference> caughtExceptions = collectCaughtExceptions(node, block);
Set<TypeReference> filteredExceptions = collectFilteredExceptions(node, throwingInstruction);
Set<TypeReference> exceptions = computeThrownMinusCaughtExceptions(thrownExceptions, caughtExceptions);
if (node.getMethod().getName().toString().equals("foo") && !exceptions.isEmpty()) {
System.out.println(throwingInstruction);
}
intraproceduralExceptions.get(node).addAll(exceptions);
thrownExceptions.removeAll(filteredExceptions);
thrownExceptions.removeAll(caughtExceptions);
intraproceduralExceptions.get(node).addAll(thrownExceptions);
}
}
}
@ -82,14 +86,24 @@ public class IntraproceduralResult {
}
}
private Set<TypeReference> computeThrownMinusCaughtExceptions(Set<TypeReference> thrownExceptions,
Set<TypeReference> caughtExceptions) {
Set<TypeReference> result = new LinkedHashSet<>();
private Set<TypeReference> collectFilteredExceptions(CGNode node, SSAInstruction throwingInstruction) {
if (filter != null) {
Set<TypeReference> filtered = new LinkedHashSet<>();
Collection<FilteredException> filters = filter.getFilter(node).filteredExceptions(throwingInstruction);
for (FilteredException filter : filters) {
if (filter.isSubclassFiltered()) {
for (IClass iclass : this.classHierachy.computeSubClasses(filter.getException())) {
filtered.add(iclass.getReference());
}
} else {
filtered.add(filter.getException());
}
}
return filtered;
} else {
return Collections.emptySet();
}
result.addAll(thrownExceptions);
result.removeAll(caughtExceptions);
return result;
}
/**
@ -193,7 +207,7 @@ public class IntraproceduralResult {
return result;
}
public Set<TypeReference> getFilteredExceptions(CGNode node, CallSiteReference callsite) {
public Set<TypeReference> getCaughtExceptions(CGNode node, CallSiteReference callsite) {
Set<TypeReference> result = new LinkedHashSet<>();
IntSet iindices = node.getIR().getCallInstructionIndices(callsite);
@ -206,10 +220,6 @@ public class IntraproceduralResult {
throw new IllegalArgumentException("The given callsite dose not correspond to an invoke instruction." + instruction);
}
// SSAInvokeInstruction invoke = (SSAInvokeInstruction) instruction;
// if (instruction == null) {
// throw new IllegalStateException();
// }
ISSABasicBlock block = node.getIR().getBasicBlockForInstruction(instruction);
if (result.isEmpty()) {
result.addAll(collectCaughtExceptions(node, block));

View File

@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural;
import com.ibm.wala.analysis.arraybounds.ArrayOutOfBoundsAnalysis;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.cfg.exceptionpruning.ExceptionFilter;
import com.ibm.wala.ipa.cfg.exceptionpruning.filter.ArrayOutOfBoundFilter;
import com.ibm.wala.ssa.SSAInstruction;
public class ArrayOutOfBoundInterFilter extends StoringExceptionFilter<SSAInstruction>{
@Override
protected ExceptionFilter<SSAInstruction> computeFilter(CGNode node) {
ArrayOutOfBoundsAnalysis analysis = new ArrayOutOfBoundsAnalysis(node.getIR());
return new ArrayOutOfBoundFilter(analysis);
}
}

View File

@ -0,0 +1,51 @@
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural;
import java.util.Collection;
import java.util.LinkedList;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.cfg.exceptionpruning.ExceptionFilter;
import com.ibm.wala.ipa.cfg.exceptionpruning.filter.CombinedExceptionFilter;
public class CombinedInterproceduralExceptionFilter<Instruction> implements InterproceduralExceptionFilter<Instruction> {
private final Collection<InterproceduralExceptionFilter<Instruction>> filter;
public CombinedInterproceduralExceptionFilter() {
this.filter = new LinkedList<>();
}
public CombinedInterproceduralExceptionFilter(
Collection<InterproceduralExceptionFilter<Instruction>> filter) {
this.filter = filter;
}
public boolean add(InterproceduralExceptionFilter<Instruction> e) {
return this.filter.add(e);
}
public boolean addAll(
Collection<? extends InterproceduralExceptionFilter<Instruction>> c) {
return this.filter.addAll(c);
}
@Override
public ExceptionFilter<Instruction> getFilter(CGNode node) {
CombinedExceptionFilter<Instruction> result = new CombinedExceptionFilter<Instruction>();
for (InterproceduralExceptionFilter<Instruction> exceptionFilter:filter) {
result.add(exceptionFilter.getFilter(node));
}
return result;
}
}

View File

@ -0,0 +1,28 @@
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.cfg.exceptionpruning.ExceptionFilter;
public class IgnoreExceptionsInterFilter<Instruction> implements InterproceduralExceptionFilter<Instruction>{
private ExceptionFilter<Instruction> filter;
public IgnoreExceptionsInterFilter(ExceptionFilter<Instruction> filter){
this.filter = filter;
}
@Override
public ExceptionFilter<Instruction> getFilter(CGNode node) {
return filter;
}
}

View File

@ -0,0 +1,18 @@
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.cfg.exceptionpruning.ExceptionFilter;
public interface InterproceduralExceptionFilter<Instruction> {
public ExceptionFilter<Instruction> getFilter(CGNode node);
}

View File

@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural;
import com.ibm.wala.analysis.nullpointer.IntraproceduralNullPointerAnalysis;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.cfg.exceptionpruning.ExceptionFilter;
import com.ibm.wala.ipa.cfg.exceptionpruning.filter.NullPointerExceptionFilter;
import com.ibm.wala.ssa.SSAInstruction;
public class NullPointerExceptionInterFilter extends StoringExceptionFilter<SSAInstruction>{
@Override
protected ExceptionFilter<SSAInstruction> computeFilter(CGNode node) {
IntraproceduralNullPointerAnalysis analysis = new IntraproceduralNullPointerAnalysis(node.getIR());
return new NullPointerExceptionFilter(analysis);
}
}

View File

@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural;
import java.util.LinkedHashMap;
import java.util.Map;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.cfg.exceptionpruning.ExceptionFilter;
public abstract class StoringExceptionFilter<Instruction> implements InterproceduralExceptionFilter<Instruction>{
private Map<CGNode, ExceptionFilter<Instruction>> store;
public StoringExceptionFilter(){
this.store = new LinkedHashMap<>();
}
abstract protected ExceptionFilter<Instruction> computeFilter(CGNode node);
@Override
public ExceptionFilter<Instruction> getFilter(CGNode node) {
if (store.containsKey(node)) {
return store.get(node);
} else {
ExceptionFilter<Instruction> filter = computeFilter(node);
store.put(node, filter);
return filter;
}
}
}

View File

@ -0,0 +1,8 @@
/**
*
*/
/**
* @author stephan
*
*/
package com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural;