Commit 51dac9e0 authored by Lukáš Marek's avatar Lukáš Marek

trunk cleanup

this commit is start of bigger trunk cleanup wich should result in live trunk
1) trunk is reverted back to revison 575
2) trunk is branched from 577 to crate branch with SyntheticStatic stuff (not stable enough)
3) remoteval is applied to trunk
parent 2dd07726
...@@ -4,10 +4,5 @@ The DiSL framework will load the jar, parse the instrumentation specification, a ...@@ -4,10 +4,5 @@ The DiSL framework will load the jar, parse the instrumentation specification, a
The examples of simple instrumentation are in src-test directory. The examples of simple instrumentation are in src-test directory.
The test can be invoked using runTest.sh script in the root directory. The test can be invoked using runTest.sh script in the root directory.
For user defined instrumentation, it is recommended to mimic the start and build script as they are provided for the tests. For user defined instrumentation, it is recommended to mimic the start and build script as they are provided for test.
We are working on better setup scripts to ease the setup effort for developer. We are working on better setup scripts to ease the setup effort for developer.
The supported platform is Linux with installed Java and GCC.
To compile DiSL please run the "ant" command in the root directory and "make" in the src-agent-c directory.
If the make is complaining about missing java headers, modify the Makefile.local.tmpl accordingly.
...@@ -18,7 +18,7 @@ then ...@@ -18,7 +18,7 @@ then
rm .server.pid rm .server.pid
fi fi
# represents the observed program DISL_CLASS="./bin/ch/usi/dag/disl/test/$1/DiSLClass.class"
TARGET_CLASS="ch.usi.dag.disl.test.$1.TargetClass" TARGET_CLASS="ch.usi.dag.disl.test.$1.TargetClass"
# start server and take pid # start server and take pid
......
package ch.usi.dag.disl.test.staticfield;
import ch.usi.dag.disl.annotation.AfterReturning;
import ch.usi.dag.disl.annotation.Before;
import ch.usi.dag.disl.annotation.SyntheticStaticField;
import ch.usi.dag.disl.annotation.SyntheticStaticField.Scope;
import ch.usi.dag.disl.marker.BodyMarker;
import ch.usi.dag.disl.staticcontext.MethodStaticContext;
public class DiSLClass {
@SyntheticStaticField(scope = Scope.PERCLASS)
public static String s;
@SyntheticStaticField(scope = Scope.PERMETHOD)
public static String mid;
@Before(marker = BodyMarker.class, scope = "TargetClass.*", order = 2)
public static void precondition(MethodStaticContext msc) {
mid = msc.thisMethodFullName();
System.out.println("Entering " + mid + " while s is " + s);
}
@AfterReturning(marker = BodyMarker.class, scope = "TargetClass.*", order = 2)
public static void postcondition() {
System.out.println("Exiting " + mid + " while s is " + s);
}
@Before(marker = BodyMarker.class, scope = "TargetClass.print", order = 1)
public static void precondition2() {
s = "Set in TargetClass.print";
}
}
Manifest-Version: 1.0
DiSL-Classes: ch.usi.dag.disl.test.staticfield.DiSLClass
\ No newline at end of file
package ch.usi.dag.disl.test.staticfield;
public class TargetClass {
public void print() {
System.out.println("This is the body of TargetClass.print");
}
public static void main(String[] args) {
TargetClass t = new TargetClass();
t.print();
}
}
...@@ -36,7 +36,6 @@ import ch.usi.dag.disl.exception.TransformerException; ...@@ -36,7 +36,6 @@ import ch.usi.dag.disl.exception.TransformerException;
import ch.usi.dag.disl.exclusion.ExclusionSet; import ch.usi.dag.disl.exclusion.ExclusionSet;
import ch.usi.dag.disl.guard.GuardHelper; import ch.usi.dag.disl.guard.GuardHelper;
import ch.usi.dag.disl.localvar.SyntheticLocalVar; import ch.usi.dag.disl.localvar.SyntheticLocalVar;
import ch.usi.dag.disl.localvar.SyntheticStaticFieldVar;
import ch.usi.dag.disl.localvar.ThreadLocalVar; import ch.usi.dag.disl.localvar.ThreadLocalVar;
import ch.usi.dag.disl.processor.Proc; import ch.usi.dag.disl.processor.Proc;
import ch.usi.dag.disl.processor.generator.PIResolver; import ch.usi.dag.disl.processor.generator.PIResolver;
...@@ -83,8 +82,6 @@ public class DiSL { ...@@ -83,8 +82,6 @@ public class DiSL {
private final List<Snippet> snippets; private final List<Snippet> snippets;
private final List<SyntheticStaticFieldVar> syntheticStaticFields;
/** /**
* DiSL initialization * DiSL initialization
* @param useDynamicBypass enable or disable dynamic bypass instrumentation * @param useDynamicBypass enable or disable dynamic bypass instrumentation
...@@ -147,10 +144,6 @@ public class DiSL { ...@@ -147,10 +144,6 @@ public class DiSL {
// - it serves as initialization flag // - it serves as initialization flag
snippets = parsedSnippets; snippets = parsedSnippets;
// get parsed synthetic static fields
syntheticStaticFields = new LinkedList<SyntheticStaticFieldVar>(parser
.getAllLocalVars().getSyntheticStaticFields().values());
// TODO put checker here // TODO put checker here
// like After should catch normal and abnormal execution // like After should catch normal and abnormal execution
// but if you are using After (AfterThrowing) with BasicBlockMarker // but if you are using After (AfterThrowing) with BasicBlockMarker
...@@ -234,7 +227,6 @@ public class DiSL { ...@@ -234,7 +227,6 @@ public class DiSL {
System.out.println("Instrumenting method: " + className System.out.println("Instrumenting method: " + className
+ Constants.CLASS_DELIM + methodName + "(" + methodDesc + Constants.CLASS_DELIM + methodName + "(" + methodDesc
+ ")"); + ")");
}
// evaluate exclusions // evaluate exclusions
for (Scope exclScope : exclusionSet) { for (Scope exclScope : exclusionSet) {
...@@ -323,8 +315,9 @@ public class DiSL { ...@@ -323,8 +315,9 @@ public class DiSL {
// *** viewing *** // *** viewing ***
Weaver.instrument(classNode, methodNode, snippetMarkings, Weaver.instrument(classNode, methodNode, snippetMarkings,
new LinkedList<SyntheticLocalVar>(usedSLVs), new LinkedList<SyntheticLocalVar>(usedSLVs), staticInfo,
syntheticStaticFields, staticInfo, piResolver); piResolver);
}
return true; return true;
} }
......
package ch.usi.dag.disl.annotation;
public @interface SyntheticStaticField {
public enum Scope {
PERCLASS, PERMETHOD
}
Scope scope() default (Scope.PERMETHOD);
}
...@@ -18,11 +18,9 @@ import org.objectweb.asm.tree.MethodNode; ...@@ -18,11 +18,9 @@ import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.analysis.Frame; import org.objectweb.asm.tree.analysis.Frame;
import org.objectweb.asm.tree.analysis.SourceValue; import org.objectweb.asm.tree.analysis.SourceValue;
import ch.usi.dag.disl.annotation.SyntheticStaticField;
import ch.usi.dag.disl.annotation.SyntheticLocal; import ch.usi.dag.disl.annotation.SyntheticLocal;
import ch.usi.dag.disl.exception.ParserException; import ch.usi.dag.disl.exception.ParserException;
import ch.usi.dag.disl.localvar.LocalVars; import ch.usi.dag.disl.localvar.LocalVars;
import ch.usi.dag.disl.localvar.SyntheticStaticFieldVar;
import ch.usi.dag.disl.localvar.SyntheticLocalVar; import ch.usi.dag.disl.localvar.SyntheticLocalVar;
import ch.usi.dag.disl.localvar.ThreadLocalVar; import ch.usi.dag.disl.localvar.ThreadLocalVar;
import ch.usi.dag.disl.util.AsmHelper; import ch.usi.dag.disl.util.AsmHelper;
...@@ -120,15 +118,6 @@ abstract class AbstractParser { ...@@ -120,15 +118,6 @@ abstract class AbstractParser {
continue; continue;
} }
// static local
if (annotationType.equals(Type.getType(SyntheticStaticField.class))) {
SyntheticStaticFieldVar slv = parseSyntheticStaticField(
className, field, annotation);
result.getSyntheticStaticFields().put(slv.getID(), slv);
continue;
}
throw new ParserException("Field " + className + "." throw new ParserException("Field " + className + "."
+ field.name + " has unsupported DiSL annotation"); + field.name + " has unsupported DiSL annotation");
} }
...@@ -382,40 +371,4 @@ abstract class AbstractParser { ...@@ -382,40 +371,4 @@ abstract class AbstractParser {
} }
} }
} }
private SyntheticStaticFieldVar parseSyntheticStaticField(String className,
FieldNode field, AnnotationNode annotation) throws ParserException {
// check if field is static
if ((field.access & Opcodes.ACC_STATIC) == 0) {
throw new ParserException("Field " + field.name + className + "."
+ " declared as SyntheticLocalField but is not static");
}
// parse annotation data
STLAnnotaionData slad = new STLAnnotaionData();
ParserHelper.parseAnnotation(slad, annotation);
SyntheticStaticField.Scope ssfScope = SyntheticStaticField.Scope.PERMETHOD;
if (slad.scope != null) {
// enum is converted to array
// - first value is class name
// - second value is value name
ssfScope = SyntheticStaticField.Scope.valueOf(slad.scope[1]);
}
// field type
Type fieldType = Type.getType(field.desc);
return new SyntheticStaticFieldVar(className, field.name, fieldType,
ssfScope, field.access);
}
private static class STLAnnotaionData {
public String[] scope = null;
}
} }
...@@ -12,9 +12,6 @@ import ch.usi.dag.disl.localvar.ThreadLocalVar; ...@@ -12,9 +12,6 @@ import ch.usi.dag.disl.localvar.ThreadLocalVar;
import ch.usi.dag.disl.util.AsmHelper; import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.ClonedCode; import ch.usi.dag.disl.util.AsmHelper.ClonedCode;
/**
* Stores various information about a piece of java bytecode.
*/
public class Code { public class Code {
private InsnList instructions; private InsnList instructions;
...@@ -28,9 +25,6 @@ public class Code { ...@@ -28,9 +25,6 @@ public class Code {
// it further - can cause stack inconsistency that has to be handled // it further - can cause stack inconsistency that has to be handled
private boolean containsHandledException; private boolean containsHandledException;
/**
* Constructs the Code structure.
*/
public Code(InsnList instructions, List<TryCatchBlockNode> tryCatchBlocks, public Code(InsnList instructions, List<TryCatchBlockNode> tryCatchBlocks,
Set<SyntheticLocalVar> referencedSLVs, Set<SyntheticLocalVar> referencedSLVs,
Set<ThreadLocalVar> referencedTLVs, Set<ThreadLocalVar> referencedTLVs,
...@@ -49,58 +43,34 @@ public class Code { ...@@ -49,58 +43,34 @@ public class Code {
this.containsHandledException = containsHandledException; this.containsHandledException = containsHandledException;
} }
/**
* Returns an ASM instruction list.
*/
public InsnList getInstructions() { public InsnList getInstructions() {
return instructions; return instructions;
} }
/**
* Returns list of exceptions (as represented in ASM).
*/
public List<TryCatchBlockNode> getTryCatchBlocks() { public List<TryCatchBlockNode> getTryCatchBlocks() {
return tryCatchBlocks; return tryCatchBlocks;
} }
/**
* Returns list of all synthetic local variables referenced in the code.
*/
public Set<SyntheticLocalVar> getReferencedSLVs() { public Set<SyntheticLocalVar> getReferencedSLVs() {
return referencedSLVs; return referencedSLVs;
} }
/**
* Returns list of all thread local variables referenced in the code.
*/
public Set<ThreadLocalVar> getReferencedTLVs() { public Set<ThreadLocalVar> getReferencedTLVs() {
return referencedTLVs; return referencedTLVs;
} }
/**
* Returns list of all static contexts referenced in the code.
*/
public Set<StaticContextMethod> getStaticContexts() { public Set<StaticContextMethod> getStaticContexts() {
return staticContexts; return staticContexts;
} }
/**
* Returns true if the code is using dynamic context. False otherwise.
*/
public boolean usesDynamicContext() { public boolean usesDynamicContext() {
return usesDynamicContext; return usesDynamicContext;
} }
/**
* Returns true if the code is using class context. False otherwise.
*/
public boolean usesClassContext() { public boolean usesClassContext() {
return usesClassContext; return usesClassContext;
} }
/**
* Returns true if the code contains catch block (handles exception).
*/
public boolean containsHandledException() { public boolean containsHandledException() {
return containsHandledException; return containsHandledException;
} }
......
...@@ -9,8 +9,6 @@ public class LocalVars { ...@@ -9,8 +9,6 @@ public class LocalVars {
new HashMap<String, SyntheticLocalVar>(); new HashMap<String, SyntheticLocalVar>();
private Map<String, ThreadLocalVar> threadLocals = private Map<String, ThreadLocalVar> threadLocals =
new HashMap<String, ThreadLocalVar>(); new HashMap<String, ThreadLocalVar>();
private Map<String, SyntheticStaticFieldVar> syntheticStaticFields =
new HashMap<String, SyntheticStaticFieldVar>();
public Map<String, SyntheticLocalVar> getSyntheticLocals() { public Map<String, SyntheticLocalVar> getSyntheticLocals() {
return syntheticLocals; return syntheticLocals;
...@@ -20,14 +18,9 @@ public class LocalVars { ...@@ -20,14 +18,9 @@ public class LocalVars {
return threadLocals; return threadLocals;
} }
public Map<String, SyntheticStaticFieldVar> getSyntheticStaticFields() {
return syntheticStaticFields;
}
public void putAll(LocalVars localVars) { public void putAll(LocalVars localVars) {
syntheticLocals.putAll(localVars.getSyntheticLocals()); syntheticLocals.putAll(localVars.getSyntheticLocals());
threadLocals.putAll(localVars.getThreadLocals()); threadLocals.putAll(localVars.getThreadLocals());
syntheticStaticFields.putAll(localVars.getSyntheticStaticFields());
} }
} }
package ch.usi.dag.disl.localvar;
import org.objectweb.asm.Type;
import ch.usi.dag.disl.annotation.SyntheticStaticField.Scope;
public class SyntheticStaticFieldVar extends AbstractLocalVar {
private int access;
private Scope scope;
public SyntheticStaticFieldVar(String className, String fieldName, Type type,
Scope scope, int access) {
super(className, fieldName, type);
this.scope = scope;
this.access = access;
}
public String getTypeAsDesc() {
return getType().getDescriptor();
}
public int getAccess() {
return access;
}
public Scope getScope() {
return scope;
}
}
...@@ -20,7 +20,7 @@ public class BasicBlockMarker extends AbstractDWRMarker { ...@@ -20,7 +20,7 @@ public class BasicBlockMarker extends AbstractDWRMarker {
List<AbstractInsnNode> seperators = BasicBlockCalc.getAll( List<AbstractInsnNode> seperators = BasicBlockCalc.getAll(
methodNode.instructions, methodNode.tryCatchBlocks, isPrecise); methodNode.instructions, methodNode.tryCatchBlocks, isPrecise);
AbstractInsnNode last = AsmHelper.skipVirtualInsns( AbstractInsnNode last = AsmHelper.skipVirualInsns(
methodNode.instructions.getLast(), false); methodNode.instructions.getLast(), false);
seperators.add(last); seperators.add(last);
...@@ -34,7 +34,7 @@ public class BasicBlockMarker extends AbstractDWRMarker { ...@@ -34,7 +34,7 @@ public class BasicBlockMarker extends AbstractDWRMarker {
end = end.getPrevious(); end = end.getPrevious();
} }
regions.add(new MarkedRegion(start, AsmHelper.skipVirtualInsns(end, regions.add(new MarkedRegion(start, AsmHelper.skipVirualInsns(end,
false))); false)));
} }
......
...@@ -24,7 +24,7 @@ public class ExceptionHandlerMarker extends AbstractDWRMarker { ...@@ -24,7 +24,7 @@ public class ExceptionHandlerMarker extends AbstractDWRMarker {
for (TryCatchBlockNode tcb : method.tryCatchBlocks) { for (TryCatchBlockNode tcb : method.tryCatchBlocks) {
List<AbstractInsnNode> exits = cfg.visit(tcb.handler); List<AbstractInsnNode> exits = cfg.visit(tcb.handler);
regions.add(new MarkedRegion(AsmHelper.skipVirtualInsns(tcb.handler, regions.add(new MarkedRegion(AsmHelper.skipVirualInsns(tcb.handler,
true), exits)); true), exits));
} }
......
...@@ -18,8 +18,8 @@ public class TryClauseMarker extends AbstractDWRMarker { ...@@ -18,8 +18,8 @@ public class TryClauseMarker extends AbstractDWRMarker {
for (TryCatchBlockNode tcb : method.tryCatchBlocks) { for (TryCatchBlockNode tcb : method.tryCatchBlocks) {
AbstractInsnNode start = AsmHelper.skipVirtualInsns(tcb.start, true); AbstractInsnNode start = AsmHelper.skipVirualInsns(tcb.start, true);
AbstractInsnNode end = AsmHelper.skipVirtualInsns(tcb.end, false); AbstractInsnNode end = AsmHelper.skipVirualInsns(tcb.end, false);
regions.add(new MarkedRegion(start, end)); regions.add(new MarkedRegion(start, end));
} }
......
...@@ -6,15 +6,7 @@ import org.objectweb.asm.tree.AbstractInsnNode; ...@@ -6,15 +6,7 @@ import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
/**
* Holds information about a region where a snippet will be woven. The shadow
* contains two type of regions. Logical region which is available directly in
* the shadow is designed mainly for static analysis and represents a region
* which is logically captured. Weaving region is designed as a guidance for the
* weaver, where exactly should be the code woven. Note that normally are the
* regions same but can differ in cases where specific instrumentation is
* needed.
*/
public class Shadow { public class Shadow {
protected ClassNode classNode; protected ClassNode classNode;
...@@ -26,10 +18,6 @@ public class Shadow { ...@@ -26,10 +18,6 @@ public class Shadow {
private WeavingRegion weavingRegion; private WeavingRegion weavingRegion;
/**
* Holds exact information where the code will be woven. This structure is
* a guiding source for the weaver.
*/
public static class WeavingRegion { public static class WeavingRegion {
// NOTE: "ends" can be null. This means, that we have the special case // NOTE: "ends" can be null. This means, that we have the special case
...@@ -115,44 +103,26 @@ public class Shadow { ...@@ -115,44 +103,26 @@ public class Shadow {
this.weavingRegion = sa.weavingRegion; this.weavingRegion = sa.weavingRegion;
} }
/**
* Returns class node of the class where the shadow is defined.
*/
public ClassNode getClassNode() { public ClassNode getClassNode() {
return classNode; return classNode;
} }
/**
* Returns method node of the method where the shadow is defined.
*/
public MethodNode getMethodNode() { public MethodNode getMethodNode() {
return methodNode; return methodNode;
} }
/**
* Returns snippet that will be woven.
*/
public Snippet getSnippet() { public Snippet getSnippet() {
return snippet; return snippet;
} }
/**
* Returns region start (this region is designed for static analysis)
*/
public AbstractInsnNode getRegionStart() { public AbstractInsnNode getRegionStart() {
return regionStart; return regionStart;
} }
/**
* Returns region ends (this region is designed for static analysis)
*/
public List<AbstractInsnNode> getRegionEnds() { public List<AbstractInsnNode> getRegionEnds() {
return regionEnds; return regionEnds;
} }
/**
* Returns weaving region (this region is designed for weaver)
*/
public WeavingRegion getWeavingRegion() { public WeavingRegion getWeavingRegion() {
return weavingRegion; return weavingRegion;
} }
......
...@@ -13,9 +13,6 @@ import ch.usi.dag.disl.marker.Marker; ...@@ -13,9 +13,6 @@ import ch.usi.dag.disl.marker.Marker;
import ch.usi.dag.disl.processor.Proc; import ch.usi.dag.disl.processor.Proc;
import ch.usi.dag.disl.scope.Scope; import ch.usi.dag.disl.scope.Scope;
/**
* Holds all the information about a snippet.
*/
public class Snippet implements Comparable<Snippet> { public class Snippet implements Comparable<Snippet> {
private String originClassName; private String originClassName;
...@@ -29,9 +26,6 @@ public class Snippet implements Comparable<Snippet> { ...@@ -29,9 +26,6 @@ public class Snippet implements Comparable<Snippet> {
private SnippetUnprocessedCode unprocessedCode; private SnippetUnprocessedCode unprocessedCode;
private SnippetCode code; private SnippetCode code;
/**
* Creates snippet structure.
*/
public Snippet(String originClassName, String originMethodName, public Snippet(String originClassName, String originMethodName,
Class<?> annotationClass, Marker marker, Scope scope, Method guard, Class<?> annotationClass, Marker marker, Scope scope, Method guard,
int order, SnippetUnprocessedCode unprocessedCode) { int order, SnippetUnprocessedCode unprocessedCode) {
...@@ -46,72 +40,42 @@ public class Snippet implements Comparable<Snippet> { ...@@ -46,72 +40,42 @@ public class Snippet implements Comparable<Snippet> {
this.unprocessedCode = unprocessedCode; this.unprocessedCode = unprocessedCode;
} }
/**
* Get the class name where the snippet is defined.
*/
public String getOriginClassName() { public String getOriginClassName() {
return originClassName; return originClassName;
} }
/**
* Get the method name where the snippet is defined.
*/
public String getOriginMethodName() { public String getOriginMethodName() {
return originMethodName; return originMethodName;
} }
/**
* Get the snippet annotation class.
*/
public Class<?> getAnnotationClass() { public Class<?> getAnnotationClass() {
return annotationClass; return annotationClass;
} }
/**
* Get the snippet marker.
*/
public Marker getMarker() { public Marker getMarker() {
return marker; return marker;
} }
/**
* Get the snippet scope.
*/
public Scope getScope() { public Scope getScope() {
return scope; return scope;
} }
/**
* Get the snippet guard.
*/
public Method getGuard() { public Method getGuard() {
return guard; return guard;
} }
/**
* Get the snippet order.
*/
public int getOrder() { public int getOrder() {
return order; return order;
} }
/**
* Get the snippet code.
*/
public SnippetCode getCode() { public SnippetCode getCode() {
return code; return code;
} }
/**
* Compares snippets according to order.
*/
public int compareTo(Snippet o) { public int compareTo(Snippet o) {
return o.getOrder() - order; return o.getOrder() - order;
} }
/**
* Initializes snippet -- prepares the snippet code.
*/
public void init(LocalVars allLVs, Map<Type, Proc> processors, public void init(LocalVars allLVs, Map<Type, Proc> processors,
boolean exceptHandler, boolean useDynamicBypass) boolean exceptHandler, boolean useDynamicBypass)
throws StaticContextGenException, ReflectionException, throws StaticContextGenException, ReflectionException,
......