Commit f6b1a5fa authored by Lukáš Marek's avatar Lukáš Marek

Merged changes from the stable branch disl_1.0.x -r 575:581

parent 4eaf8605
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>DiSL-RE</name>
<name>DiSL-1.0.x</name>
<comment></comment>
<projects>
</projects>
......
......@@ -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 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.
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.
......@@ -21,14 +21,7 @@ then
rm ${SERVER_FILE}
fi
# kill running RE server
if [ -e ${RE_SERVER_FILE} ]
then
kill -KILL `cat ${RE_SERVER_FILE}`
rm ${RE_SERVER_FILE}
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"
# start server and take pid
......
......@@ -227,6 +227,7 @@ public class DiSL {
System.out.println("Instrumenting method: " + className
+ Constants.CLASS_DELIM + methodName + "(" + methodDesc
+ ")");
}
// evaluate exclusions
for (Scope exclScope : exclusionSet) {
......@@ -317,8 +318,7 @@ public class DiSL {
Weaver.instrument(classNode, methodNode, snippetMarkings,
new LinkedList<SyntheticLocalVar>(usedSLVs), staticInfo,
piResolver);
}
return true;
}
......
......@@ -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.ClonedCode;
/**
* Stores various information about a piece of java bytecode.
*/
public class Code {
private InsnList instructions;
......@@ -25,6 +28,9 @@ public class Code {
// it further - can cause stack inconsistency that has to be handled
private boolean containsHandledException;
/**
* Constructs the Code structure.
*/
public Code(InsnList instructions, List<TryCatchBlockNode> tryCatchBlocks,
Set<SyntheticLocalVar> referencedSLVs,
Set<ThreadLocalVar> referencedTLVs,
......@@ -43,34 +49,58 @@ public class Code {
this.containsHandledException = containsHandledException;
}
/**
* Returns an ASM instruction list.
*/
public InsnList getInstructions() {
return instructions;
}
/**
* Returns list of exceptions (as represented in ASM).
*/
public List<TryCatchBlockNode> getTryCatchBlocks() {
return tryCatchBlocks;
}
/**
* Returns list of all synthetic local variables referenced in the code.
*/
public Set<SyntheticLocalVar> getReferencedSLVs() {
return referencedSLVs;
}
/**
* Returns list of all thread local variables referenced in the code.
*/
public Set<ThreadLocalVar> getReferencedTLVs() {
return referencedTLVs;
}
/**
* Returns list of all static contexts referenced in the code.
*/
public Set<StaticContextMethod> getStaticContexts() {
return staticContexts;
}
/**
* Returns true if the code is using dynamic context. False otherwise.
*/
public boolean usesDynamicContext() {
return usesDynamicContext;
}
/**
* Returns true if the code is using class context. False otherwise.
*/
public boolean usesClassContext() {
return usesClassContext;
}
/**
* Returns true if the code contains catch block (handles exception).
*/
public boolean containsHandledException() {
return containsHandledException;
}
......
......@@ -6,7 +6,15 @@ import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
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 {
protected ClassNode classNode;
......@@ -18,6 +26,10 @@ public class Shadow {
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 {
// NOTE: "ends" can be null. This means, that we have the special case
......@@ -103,26 +115,44 @@ public class Shadow {
this.weavingRegion = sa.weavingRegion;
}
/**
* Returns class node of the class where the shadow is defined.
*/
public ClassNode getClassNode() {
return classNode;
}
/**
* Returns method node of the method where the shadow is defined.
*/
public MethodNode getMethodNode() {
return methodNode;
}
/**
* Returns snippet that will be woven.
*/
public Snippet getSnippet() {
return snippet;
}
/**
* Returns region start (this region is designed for static analysis)
*/
public AbstractInsnNode getRegionStart() {
return regionStart;
}
/**
* Returns region ends (this region is designed for static analysis)
*/
public List<AbstractInsnNode> getRegionEnds() {
return regionEnds;
}
/**
* Returns weaving region (this region is designed for weaver)
*/
public WeavingRegion getWeavingRegion() {
return weavingRegion;
}
......
......@@ -13,6 +13,9 @@ import ch.usi.dag.disl.marker.Marker;
import ch.usi.dag.disl.processor.Proc;
import ch.usi.dag.disl.scope.Scope;
/**
* Holds all the information about a snippet.
*/
public class Snippet implements Comparable<Snippet> {
private String originClassName;
......@@ -26,6 +29,9 @@ public class Snippet implements Comparable<Snippet> {
private SnippetUnprocessedCode unprocessedCode;
private SnippetCode code;
/**
* Creates snippet structure.
*/
public Snippet(String originClassName, String originMethodName,
Class<?> annotationClass, Marker marker, Scope scope, Method guard,
int order, SnippetUnprocessedCode unprocessedCode) {
......@@ -40,42 +46,72 @@ public class Snippet implements Comparable<Snippet> {
this.unprocessedCode = unprocessedCode;
}
/**
* Get the class name where the snippet is defined.
*/
public String getOriginClassName() {
return originClassName;
}
/**
* Get the method name where the snippet is defined.
*/
public String getOriginMethodName() {
return originMethodName;
}
/**
* Get the snippet annotation class.
*/
public Class<?> getAnnotationClass() {
return annotationClass;
}
/**
* Get the snippet marker.
*/
public Marker getMarker() {
return marker;
}
/**
* Get the snippet scope.
*/
public Scope getScope() {
return scope;
}
/**
* Get the snippet guard.
*/
public Method getGuard() {
return guard;
}
/**
* Get the snippet order.
*/
public int getOrder() {
return order;
}
/**
* Get the snippet code.
*/
public SnippetCode getCode() {
return code;
}
/**
* Compares snippets according to order.
*/
public int compareTo(Snippet o) {
return o.getOrder() - order;
}
/**
* Initializes snippet -- prepares the snippet code.
*/
public void init(LocalVars allLVs, Map<Type, Proc> processors,
boolean exceptHandler, boolean useDynamicBypass)
throws StaticContextGenException, ReflectionException,
......
......@@ -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.ClonedCode;
/**
* Stores the information about snippet code.
*/
public class SnippetCode extends Code {
private boolean usesProcessorContext;
......@@ -42,6 +45,9 @@ public class SnippetCode extends Code {
this.usesProcessorContext = usesProcessorContext;
}
/**
* Returns list of all argument processors referenced in the code.
*/
public Map<Integer, ProcInvocation> getInvokedProcessors() {
return invokedProcessors;
}
......
......@@ -32,6 +32,9 @@ import ch.usi.dag.disl.processorcontext.ArgumentProcessorContext;
import ch.usi.dag.disl.processorcontext.ArgumentProcessorMode;
import ch.usi.dag.disl.util.AsmHelper;
/**
* Contains unprocessed code of the Snippet.
*/
public class SnippetUnprocessedCode extends UnprocessedCode {
private String className;
......@@ -39,6 +42,9 @@ public class SnippetUnprocessedCode extends UnprocessedCode {
private boolean dynamicBypass;
private boolean usesProcessorContext;
/**
* Creates unprocessed code structure.
*/
public SnippetUnprocessedCode(String className, String methodName,
InsnList instructions, List<TryCatchBlockNode> tryCatchBlocks,
Set<String> declaredStaticContexts, boolean usesDynamicContext,
......@@ -53,6 +59,9 @@ public class SnippetUnprocessedCode extends UnprocessedCode {
this.usesProcessorContext = usesProcessorContext;
}
/**
* Processes the stored data and creates snippet code structure.
*/
public SnippetCode process(LocalVars allLVs, Map<Type, Proc> processors,
Marker marker, boolean exceptHandler, boolean useDynamicBypass)
throws StaticContextGenException, ReflectionException,
......
......@@ -2,6 +2,10 @@ package ch.usi.dag.disl.staticcontext;
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 {
protected Shadow staticContextData;
......
......@@ -2,13 +2,18 @@ package ch.usi.dag.disl.staticcontext;
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 {
// It is mandatory to implement this interface
// NOTE: 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
/**
* Receives static context data. Call to this method precedes a static
* context method invocation.
*/
public void staticContextData(Shadow sa);
}
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 {
/**
* 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;
/**
* 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();
}
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