Commit 5b69bb40 authored by Lukáš Marek's avatar Lukáš Marek

Added some documentation + cleanups

parent c1e34971
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<projectDescription> <projectDescription>
<name>DiSL</name> <name>DiSL-1.0.x</name>
<comment></comment> <comment></comment>
<projects> <projects>
</projects> </projects>
......
...@@ -4,5 +4,10 @@ The DiSL framework will load the jar, parse the instrumentation specification, a ...@@ -4,5 +4,10 @@ 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 test. For user defined instrumentation, it is recommended to mimic the start and build script as they are provided for the tests.
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
DISL_CLASS="./bin/ch/usi/dag/disl/test/$1/DiSLClass.class" # represents the observed program
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
......
...@@ -12,6 +12,9 @@ import ch.usi.dag.disl.localvar.ThreadLocalVar; ...@@ -12,6 +12,9 @@ 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;
...@@ -25,6 +28,9 @@ public class Code { ...@@ -25,6 +28,9 @@ 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,
...@@ -43,34 +49,58 @@ public class Code { ...@@ -43,34 +49,58 @@ 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;
} }
......
...@@ -6,7 +6,15 @@ import org.objectweb.asm.tree.AbstractInsnNode; ...@@ -6,7 +6,15 @@ 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;
...@@ -18,6 +26,10 @@ public class Shadow { ...@@ -18,6 +26,10 @@ 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
...@@ -103,26 +115,44 @@ public class Shadow { ...@@ -103,26 +115,44 @@ 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,6 +13,9 @@ import ch.usi.dag.disl.marker.Marker; ...@@ -13,6 +13,9 @@ 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;
...@@ -26,6 +29,9 @@ public class Snippet implements Comparable<Snippet> { ...@@ -26,6 +29,9 @@ 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) {
...@@ -40,42 +46,72 @@ public class Snippet implements Comparable<Snippet> { ...@@ -40,42 +46,72 @@ 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,
......
...@@ -16,6 +16,9 @@ import ch.usi.dag.disl.localvar.ThreadLocalVar; ...@@ -16,6 +16,9 @@ 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 the information about snippet code.
*/
public class SnippetCode extends Code { public class SnippetCode extends Code {
private boolean usesProcessorContext; private boolean usesProcessorContext;
...@@ -42,6 +45,9 @@ public class SnippetCode extends Code { ...@@ -42,6 +45,9 @@ public class SnippetCode extends Code {
this.usesProcessorContext = usesProcessorContext; this.usesProcessorContext = usesProcessorContext;
} }
/**
* Returns list of all argument processors referenced in the code.
*/
public Map<Integer, ProcInvocation> getInvokedProcessors() { public Map<Integer, ProcInvocation> getInvokedProcessors() {
return invokedProcessors; return invokedProcessors;
} }
......
...@@ -32,6 +32,9 @@ import ch.usi.dag.disl.processorcontext.ArgumentProcessorContext; ...@@ -32,6 +32,9 @@ import ch.usi.dag.disl.processorcontext.ArgumentProcessorContext;
import ch.usi.dag.disl.processorcontext.ArgumentProcessorMode; import ch.usi.dag.disl.processorcontext.ArgumentProcessorMode;
import ch.usi.dag.disl.util.AsmHelper; import ch.usi.dag.disl.util.AsmHelper;
/**
* Contains unprocessed code of the Snippet.
*/
public class SnippetUnprocessedCode extends UnprocessedCode { public class SnippetUnprocessedCode extends UnprocessedCode {
private String className; private String className;
...@@ -39,6 +42,9 @@ public class SnippetUnprocessedCode extends UnprocessedCode { ...@@ -39,6 +42,9 @@ public class SnippetUnprocessedCode extends UnprocessedCode {
private boolean dynamicBypass; private boolean dynamicBypass;
private boolean usesProcessorContext; private boolean usesProcessorContext;
/**
* Creates unprocessed code structure.
*/
public SnippetUnprocessedCode(String className, String methodName, public SnippetUnprocessedCode(String className, String methodName,
InsnList instructions, List<TryCatchBlockNode> tryCatchBlocks, InsnList instructions, List<TryCatchBlockNode> tryCatchBlocks,
Set<String> declaredStaticContexts, boolean usesDynamicContext, Set<String> declaredStaticContexts, boolean usesDynamicContext,
...@@ -53,6 +59,9 @@ public class SnippetUnprocessedCode extends UnprocessedCode { ...@@ -53,6 +59,9 @@ public class SnippetUnprocessedCode extends UnprocessedCode {
this.usesProcessorContext = usesProcessorContext; this.usesProcessorContext = usesProcessorContext;
} }
/**
* Processes the stored data and creates snippet code structure.
*/
public SnippetCode process(LocalVars allLVs, Map<Type, Proc> processors, public SnippetCode process(LocalVars allLVs, Map<Type, Proc> processors,
Marker marker, boolean exceptHandler, boolean useDynamicBypass) Marker marker, boolean exceptHandler, boolean useDynamicBypass)
throws StaticContextGenException, ReflectionException, throws StaticContextGenException, ReflectionException,
......
...@@ -2,6 +2,10 @@ package ch.usi.dag.disl.staticcontext; ...@@ -2,6 +2,10 @@ package ch.usi.dag.disl.staticcontext;
import ch.usi.dag.disl.snippet.Shadow; import ch.usi.dag.disl.snippet.Shadow;
/**
* Provides simple implementation of StaticContext that holds the static context
* data in a protected field.
*/
public abstract class AbstractStaticContext implements StaticContext { public abstract class AbstractStaticContext implements StaticContext {
protected Shadow staticContextData; protected Shadow staticContextData;
......
...@@ -2,13 +2,18 @@ package ch.usi.dag.disl.staticcontext; ...@@ -2,13 +2,18 @@ package ch.usi.dag.disl.staticcontext;
import ch.usi.dag.disl.snippet.Shadow; import ch.usi.dag.disl.snippet.Shadow;
/**
* Every static context class has to implement this interface.
*
* All static context methods should follow convention:
* a) static context methods does not have parameters
* b) return value can be only basic type or String
*/
public interface StaticContext { public interface StaticContext {
// It is mandatory to implement this interface /**
* Receives static context data. Call to this method precedes a static
// NOTE: all static context methods should follow convention: * context method invocation.
// a) static context methods does not have parameters */
// b) return value can be only basic type or String
public void staticContextData(Shadow sa); public void staticContextData(Shadow sa);
} }
package ch.usi.dag.disl.transformer; package ch.usi.dag.disl.transformer;
/**
* Allows to transform a class before it is passed to DiSL. The transformer
* class has to be specified in the instrumentation manifest.
*/
public interface Transformer { public interface Transformer {
/**
* The transformation interface. The class to be transformed is passed as
* an argument and the transformed class is returned.
*
* @param classfileBuffer class to be transformed
* @return transformed class
*/
byte[] transform(byte[] classfileBuffer) throws Exception; byte[] transform(byte[] classfileBuffer) throws Exception;
/**
* If this method returns true, not instrumented classes are still
* set as changed and returned by DiSL as modified. Otherwise, the DiSL will
* report class as unmodified.
*
* @return propagation flag
*/
boolean propagateUninstrumentedClasses(); boolean propagateUninstrumentedClasses();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment