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

Merged changes from stable branch disl_1.0.x -r 599:720

parent 5114d2b9
......@@ -6,7 +6,7 @@
<classpathentry kind="src" path="src-agent-java"/>
<classpathentry kind="src" path="src-test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/asm-debug-all-4.0.jar"/>
<classpathentry kind="lib" path="build/eclipse-dynamicbypass.jar"/>
<classpathentry kind="lib" path="lib/asm-debug-all-4.1.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
DiSL
====
DiSL is inspired by AOP, but in contrast to mainstream AOP languages, it features
an open join point model where any region of bytecodes can be selected as a join
point (i.e., code location to be instrumented). DiSL reconciles high-level
language constructs resulting in concise instrumentations, high expressiveness,
and efficiency of the inserted instrumentation code. Thanks to the
pointcut/advice model adopted by DiSL, instrumentations are similarly compact as
aspects written in AspectJ. However, in contrast to AspectJ, DiSL does not
restrict the code locations that can be instrumented, and the code generated by
DiSL avoids expensive operations (such as object allocations that are not visible
to the programmer). Furthermore, DiSL supports instrumentations with complete
bytecode coverage out-of-the-box and avoids structural modifications of classes
that would be visible through reflection and could break the instrumented code.
DiSL is a Java bytecode instrumentation framework intended for observation
of programs executing in the Java Virtual Machine. It has been mainly used
for development of dynamic program analysis instrumentations, but it can be
used equally well to develop instrumentations for, e.g. runtime performance
monitoring, or other tasks not bent on altering program execution.
DiSL is inspired by AOP, but in contrast to mainstream AOP languages, it
features an open join point model where any region of bytecodes can serve as
a join point (i.e., code location to be instrumented). DiSL also reconciles
high-level language concepts, such as the pointcut/advice programming model
found in AOP, with high expressiveness, and efficiency of bytecode
manipulation performed using low-level libraries such as ASM. As a result,
instrumentations written using DiSL almost as compact as aspects written in
AspectJ, but perform about as fast as those written using ASM.
However, in contrast to AspectJ, DiSL does not restrict the code locations
that can be instrumented, and the code generated by DiSL avoids expensive
operations (such as object allocations that are not visible to the
programmer). Furthermore, DiSL supports instrumentations with complete
bytecode coverage out-of-the-box and avoids structural modifications of
classes that would be visible through reflection and could break the
instrumented code.
link: http://forge.ow2.org/projects/disl/
INSTALL
=======
DiSL currently fully supports Linux with installed Java, ant, GCC and make.
DiSL currently fully supports "Linux" and "OS X" platforms with Java, ant, GCC
and make installed and found on the executable path. DiSL has been used on the
Windows/Cygwin platform as well, but it was not extensively tested there.
While most of the DiSL is written in Java, it requires a JVM enhanced with a
native agent written in C, which must be compiled first. For that, the simple
build system needs to know where your JDK is installed to be able to find JNI
header files for your platform. On many systems, the JAVA_HOME environment
variable points to the root of the JDK installation and you should be fine.
If this is not the case, please enter the src-agent-c directory, copy the
Makefile.local.tmpl file to Makefile.local and modify it to set the JAVA_HOME
variable to point to the root of the JDK installation you want to use.
Finally, to compile DiSL, run the "ant" command in the root directory.
You can create javadoc documentation by running "ant javadoc".
To compile DiSL please run the "ant" command in the root directory. If "make" is
complaining about missing java headers, modify the Makefile.local.tmpl
accordingly.
EXAMPLES
========
......@@ -31,13 +55,15 @@ EXAMPLES
For the basic instrumentation example, please look in the example directory.
Also the src-test directory contains simple examples of DiSL features.
DOCUMENTATION
=============
Please look at http://disl.projects.ow2.org/xwiki/bin/view/Main/Doc.
USER ERRORS
===========
If you get an java error during instrumentation or running your application,
If you get a Java error during instrumentation or running your application,
please look at USERERRORS document describing most common problems.
asm.lib=asm-debug-all-4.0.jar
asm.lib=asm-debug-all-4.1.jar
asm.path=lib/${asm.lib}
src.disl=src
......
......@@ -176,6 +176,10 @@
</target>
<target name="javadoc" depends="package,eclipse">
<javadoc access="public" author="true" overview="doc/overview.html" classpath="build/eclipse-dynamicbypass.jar:${asm.path}" destdir="doc" nodeprecated="false" nodeprecatedlist="false" noindex="false" nonavbar="false" notree="false" packagenames="ch.usi.dag.disl.guardcontext,ch.usi.dag.disl.staticcontext,ch.usi.dag.disl.dynamiccontext,ch.usi.dag.disl.classcontext,ch.usi.dag.disl.marker,ch.usi.dag.disl.transformer,ch.usi.dag.disl.processorcontext,ch.usi.dag.disl.annotation" source="1.7" sourcefiles="src/ch/usi/dag/disl/scope/Scope.java,src/ch/usi/dag/disl/scope/ScopeImpl.java,src/ch/usi/dag/disl/DiSL.java,src/ch/usi/dag/disl/snippet/Shadow.java" sourcepath="src-test:src-agent-java:src" splitindex="true" use="true" version="true"/>
</target>
<!-- *** test instrumentaion package *** -->
<target name="check-test-property">
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Overview</title>
</head>
<body>
<div>This documentation serves only as a developer documentation of DiSL API. For the installation notes, please look at the README file in the DiSL distribution. For learning of DiSL, please look at the basic examples and the tutorial papers.</div>
</body>
</html>
......@@ -17,7 +17,7 @@ follow the steps:
1) compile application calling "ant" in the app directory
2) compile instrumentation calling "ant" in the instrumentation directory
3) run "runApp.sh ./runApp.sh instr/build/disl-instr.jar -jar app/build/example-app.jar"
3) run "./runApp.sh instr/build/disl-instr.jar -jar app/build/example-app.jar"
The last command starts the application together with DiSL. The output of the
application and the applied instrumentation should be visible on command line.
......
......@@ -11,13 +11,17 @@ SOURCES=dislagent.c
# Object files needed to create library
OBJECTS=$(SOURCES:%.c=%.o)
# Library name and options needed to build it
UNAME := $(shell uname)
ifeq ($(UNAME), Linux)
LIBRARY=lib$(LIBNAME).so
endif
ifeq ($(UNAME), Darwin)
JNI_OS=linux
else ifeq ($(UNAME), Darwin)
LIBRARY=lib$(LIBNAME).jnilib
JNI_OS=darwin
else
$(error error: unsupported operating system: $(UNAME))
endif
......@@ -31,7 +35,7 @@ COMMON_FLAGS+= -W -Wall -Wextra -O3 -Wno-unused-parameter
CFLAGS += $(COMMON_FLAGS)
CFLAGS += -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux
CFLAGS += -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/$(JNI_OS)
# add debugging output
ifeq ($(DEBUG), TRUE)
......
# rename this file to Makefile.local to take effect
# if variable is not defined autodetection or default is used
#JAVA_HOME = /etc/alternatives/java_sdk/
# JAVA_HOME variable should be properly defined
# Linux - Fedora
#JAVA_HOME =/etc/alternatives/java_sdk/
# Linux - Arch Linux
#JAVA_HOME =/usr/lib/jvm/java-7-openjdk
# Mac OS X
#JAVA_HOME =/Library/Java/JavaVirtualMachines/jdk1.7.0_10.jdk/Contents/Home/
......@@ -54,7 +54,7 @@ import ch.usi.dag.disl.weaver.Weaver;
// TODO javadoc comment all
/**
* Main DiSL class providing interface for an instrumentation framework
* (normally DiSL Server)
* (normally DiSL Server).
*/
public class DiSL {
......@@ -85,7 +85,7 @@ public class DiSL {
private final List<Snippet> snippets;
/**
* DiSL initialization
* DiSL initialization.
* @param useDynamicBypass enable or disable dynamic bypass instrumentation
*/
// this method should be called only once
......@@ -477,7 +477,7 @@ public class DiSL {
}
/**
* Instruments array of bytes representing a class
* Instruments array of bytes representing a class.
*
* @param classAsBytes class as array of bytes
* @return instrumented class as array of bytes
......@@ -586,7 +586,7 @@ public class DiSL {
/**
* Termination handler - should be invoked by the instrumentation framework
* Termination handler - should be invoked by the instrumentation framework.
*/
public void terminate() {
......
......@@ -6,15 +6,17 @@ import ch.usi.dag.disl.marker.Marker;
* The After annotation instructs DiSL to insert the snippet body after the
* marked region. The snippet will be invoked after a normal exit of the region
* or after an exit caused by an exception.
*
* <br>
* <br>
* NOTE: This is only general contract. It depends on particular marker how the
* contract will be implemented.
*
* <br>
* <br>
* This annotation should be used with methods.
*
* <br>
* The method should be static, not return any values and not throw any
* exceptions.
*
* <br>
* Method argument can be StaticContext, DynamicContext, ClassContext and
* ArgumentProcessorContext.
*/
......@@ -33,44 +35,44 @@ public @interface After {
/**
* Argument for the marker (as string).
*
* Default value: ""
* <br>
* <br>
* Default value means none.
*/
String args() default ""; // cannot be null :(
/**
* Scope of the methods, where the snippet is applied.
*
* @see ch.usi.dag.disl.scope package for more info about scoping language.
*
* Default value: "*"
* <br>
* <br>
* Default value means everything.
* <br>
* @see ch.usi.dag.disl.scope.ScopeImpl ScopeImpl for more info about
* scoping language.
*/
String scope() default "*";
/**
* The guard class defining if the snippet will be inlined in particular
* region or not.
*
* Default value: Object.class - means none
* <br>
* <br>
* Default value means none.
*/
Class<? extends Object> guard() default Object.class; // cannot be null :(
/**
* Defines ordering of the snippets. Smaller number indicates that snippet
* will be inlined closer to the instrumented code.
*
* Default value: 100
*/
int order() default 100;
/**
* Advanced option. You can in general disable dynamic bypass on snippets,
* that are not using any other class.
*
* NOTE Usage of dynamic bypass is determined by the underlying
* You can in general disable dynamic bypass on snippets, that are not using
* any other class. (Advanced option)
* <br>
* NOTE: Usage of dynamic bypass is determined by the underlying
* instrumentation framework.
*
* Default value: true
*/
boolean dynamicBypass() default true;
}
......@@ -6,15 +6,17 @@ import ch.usi.dag.disl.marker.Marker;
* The AfterReturning annotation instructs DiSL to insert the snippet body after
* the marked region. The snippet will be invoked after a normal exit of the
* region.
*
* <br>
* <br>
* NOTE: This is only general contract. It depends on particular marker how the
* contract will be implemented.
*
* <br>
* <br>
* This annotation should be used with methods.
*
* <br>
* The method should be static, not return any values and not throw any
* exceptions.
*
* <br>
* Method argument can be StaticContext, DynamicContext, ClassContext and
* ArgumentProcessorContext.
*/
......@@ -33,44 +35,44 @@ public @interface AfterReturning {
/**
* Argument for the marker (as string).
*
* Default value: ""
* <br>
* <br>
* Default value means none.
*/
String args() default ""; // cannot be null :(
/**
* Scope of the methods, where the snippet is applied.
*
* @see ch.usi.dag.disl.scope package for more info about scoping language.
*
* Default value: "*"
* <br>
* <br>
* Default value means everything.
* <br>
* @see ch.usi.dag.disl.scope.ScopeImpl ScopeImpl for more info about
* scoping language.
*/
String scope() default "*";
/**
* The guard class defining if the snippet will be inlined in particular
* region or not.
*
* Default value: Object.class - means none
* <br>
* <br>
* Default value means none.
*/
Class<? extends Object> guard() default Object.class; // cannot be null :(
/**
* Defines ordering of the snippets. Smaller number indicates that snippet
* will be inlined closer to the instrumented code.
*
* Default value: 100
*/
int order() default 100;
/**
* Advanced option. You can in general disable dynamic bypass on snippets,
* that are not using any other class.
*
* NOTE Usage of dynamic bypass is determined by the underlying
* You can in general disable dynamic bypass on snippets, that are not using
* any other class. (Advanced option)
* <br>
* NOTE: Usage of dynamic bypass is determined by the underlying
* instrumentation framework.
*
* Default value: true
*/
boolean dynamicBypass() default true;
}
......@@ -6,15 +6,17 @@ import ch.usi.dag.disl.marker.Marker;
* The AfterThrowing annotation instructs DiSL to insert the snippet body after
* the marked region. The snippet will be invoked after an exit caused by an
* exception.
*
* <br>
* <br>
* NOTE: This is only general contract. It depends on particular marker how the
* contract will be implemented.
*
* <br>
* <br>
* This annotation should be used with methods.
*
* <br>
* The method should be static, not return any values and not throw any
* exceptions.
*
* <br>
* Method argument can be StaticContext, DynamicContext, ClassContext and
* ArgumentProcessorContext.
*/
......@@ -33,44 +35,44 @@ public @interface AfterThrowing {
/**
* Argument for the marker (as string).
*
* Default value: ""
* <br>
* <br>
* Default value means none.
*/
String args() default ""; // cannot be null :(
/**
* Scope of the methods, where the snippet is applied.
*
* @see ch.usi.dag.disl.scope package for more info about scoping language.
*
* Default value: "*"
* <br>
* <br>
* Default value means everything.
* <br>
* @see ch.usi.dag.disl.scope.ScopeImpl ScopeImpl for more info about
* scoping language.
*/
String scope() default "*";
/**
* The guard class defining if the snippet will be inlined in particular
* region or not.
*
* Default value: Object.class - means none
* <br>
* <br>
* Default value means none.
*/
Class<? extends Object> guard() default Object.class; // cannot be null :(
/**
* Defines ordering of the snippets. Smaller number indicates that snippet
* will be inlined closer to the instrumented code.
*
* Default value: 100
*/
int order() default 100;
/**
* Advanced option. You can in general disable dynamic bypass on snippets,
* that are not using any other class.
*
* NOTE Usage of dynamic bypass is determined by the underlying
* You can in general disable dynamic bypass on snippets, that are not using
* any other class. (Advanced option)
* <br>
* NOTE: Usage of dynamic bypass is determined by the underlying
* instrumentation framework.
*
* Default value: true
*/
boolean dynamicBypass() default true;
}
......@@ -3,19 +3,20 @@ package ch.usi.dag.disl.annotation;
/**
* Annotated class defines method for processing method arguments. The specified
* methods will be inlined into snippets to process one method argument value.
*
* <br>
* <br>
* First argument of the method is a type, that will be processed by the method.
* The allowed types are all basic types, String and Object class. The processed
* type can be extend in some special cases by ProcessAlso annotation.
* During run-time, the argument will contain a processed method argument value.
*
* ArgumentContext can be used to fetch additional data about the argument.
*
* <br>
* <br>
* This annotation should be used with classes.
*
* <br>
* The method should be static, not return any values and not throw any
* exceptions.
*
* <br>
* Method argument can be StaticContext, DynamicContext, ClassContext and
* ArgumentContext.
*/
......
......@@ -5,15 +5,17 @@ import ch.usi.dag.disl.marker.Marker;
/**
* The Before annotation instructs DiSL to insert the snippet body before the
* marked region. The snippet will be invoked before the entry of the region.
*
* <br>
* <br>
* NOTE: This is only general contract. It depends on particular marker how the
* contract will be implemented.
*
* <br>
* <br>
* This annotation should be used with methods.
*
* <br>
* The method should be static, not return any values and not throw any
* exceptions.
*
* <br>
* Method argument can be StaticContext, DynamicContext, ClassContext and
* ArgumentProcessorContext.
*/
......@@ -32,44 +34,44 @@ public @interface Before {
/**
* Argument for the marker (as string).
*
* Default value: ""
* <br>
* <br>
* Default value means none.
*/
String args() default ""; // cannot be null :(
/**
* Scope of the methods, where the snippet is applied.
*
* @see ch.usi.dag.disl.scope package for more info about scoping language.
*
* Default value: "*"
* <br>
* <br>
* Default value means everything.
* <br>
* @see ch.usi.dag.disl.scope.ScopeImpl ScopeImpl for more info about
* scoping language.
*/
String scope() default "*";
/**
* The guard class defining if the snippet will be inlined in particular
* region or not.
*
* Default value: Object.class - means none
* <br>
* <br>
* Default value means none.
*/
Class<? extends Object> guard() default Object.class; // cannot be null :(
/**
* Defines ordering of the snippets. Smaller number indicates that snippet
* will be inlined closer to the instrumented code.
*
* Default value: 100
*/
int order() default 100;
/**
* Advanced option. You can in general disable dynamic bypass on snippets,
* that are not using any other class.
*
* NOTE Usage of dynamic bypass is determined by the underlying
* You can in general disable dynamic bypass on snippets, that are not using
* any other class. (Advanced option)
* <br>
* NOTE: Usage of dynamic bypass is determined by the underlying
* instrumentation framework.
*
* Default value: true
*/
boolean dynamicBypass() default true;
}
......@@ -5,11 +5,12 @@ import java.lang.annotation.RetentionPolicy;
/**
* Marks guard validation method.
*
* <br>
* <br>
* This annotation should be used with methods.
*
* <br>
* Guard method should be static and state-less.
*
* <br>
* Method argument can be Shadow, StaticContext, GuardContext and for
* ArgumentProcessor guard also ArgumentContext.
*/
......
......@@ -2,7 +2,8 @@ package ch.usi.dag.disl.annotation;
/**
* Annotation used in ArgumentProcessor to guard specific methods.
*
* <br>
* <br>
* This annotation should be used with methods.
*/
public @interface Guarded {
......
......@@ -3,8 +3,9 @@ package ch.usi.dag.disl.annotation;
// TODO add tool that will look for Instrumentation annotation and create meta-data for jar
// http://stackoverflow.com/questions/3644069/java-6-annotation-processing-configuration-with-ant
/**
* This method denotes DiSL instrumentation class.
*
* This annotation denotes DiSL instrumentation class.
* <br>
* <br>
* This annotation should be used with classes.
*/
public @interface Instrumentation {
......
......@@ -14,6 +14,9 @@ public @interface ProcessAlso {
// NOTE because of implementation of annotations in java the defaults
// are not retrieved from here but from class mentioned above
/**
* @see ch.usi.dag.disl.annotation.ProcessAlso
*/
public enum Type {
BOOLEAN,
BYTE,
......
......@@ -6,18 +6,23 @@ package ch.usi.dag.disl.annotation;
* a method. The local variable is by default always initialized to the assigned
* value or the default value of a corresponding type. It is possible to disable
* the initialization using optional "initialize" annotation parameter.
*
* <br>
* <br>
* NOTE: Initialization can be done only within field definition.
* Java static { } construct for initialization is not supported and
* could cause invalid instrumentation.
*
* <br>
* <br>
* This annotation should be used with fields.
*
* <br>
* Field should be declared as static, and if not shared between multiple DiSL
* classes, also private.
*/
public @interface SyntheticLocal {
/**
* @see ch.usi.dag.disl.annotation.SyntheticLocal
*/
public enum Initialize {
ALWAYS, NEVER, BEST_EFFORT
}
......
......@@ -2,13 +2,14 @@ package ch.usi.dag.disl.annotation;
/**
* Indicates, that field is used for data passing between several snippets
* inlined. The field is translated into thread local variable. The thread local
* The field is translated into thread local variable. The thread local
* variable is by default always initialized the default value of a
* corresponding type. The default value can be inherited from a parent thread
* using optional inheritable annotation parameter.
*
* <br>
* <br>
* This annotation should be used with fields.
*
* <br>
* Field should be declared as static, and if not shared between multiple DiSL
* classes, also private.
*/
......
......@@ -112,7 +112,7 @@ public class UnprocessedCode {
* @param knownStAnClasses known StaticContext classes
* @param instr instruction to analyze
* @param knownMethods methods that are already known
* @return
* @return @see StaticContextMethod
* @throws StaticContextGenException
* @throws ReflectionException
*/
......
......@@ -83,16 +83,16 @@ public interface DynamicContext {
*/
<T> T getLocalVariableValue (int slotIndex, Class <T> valueType);
// TODO enable when properly implemented
// <T> T getStaticFieldValue (
// String ownerClass,
// String fieldName, String fieldDesc, Class<T> fieldType
// );
<T> T getStaticFieldValue (
String ownerClass,
String fieldName, String fieldDesc, Class<T> fieldType
);
<T> T getInstanceFieldValue (
Object instance, String ownerClass,
String fieldName, String fieldDesc, Class<T> fieldType
);
// <T> T getInstanceFieldValue (
// Object instance, String ownerClass,
// String fieldName, String fieldDesc, Class<T> fieldType
// );
}
......@@ -3,12 +3,12 @@ package ch.usi.dag.disl.guardcontext;
/**
* Guard context is used to invoke guard inside of other guard.
*
* Guard implementation has to thread-safe.
* Guard implementation has to be thread-safe.
*/
public interface GuardContext {
/**
* Invokes guard passed as argument
* Invokes guard passed as an argument.
*
* @param guardClass guard to invoke
* @return result of the invoked guard
......
......@@ -8,7 +8,7 @@ import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.snippet.Shadow.WeavingRegion;
public abstract class AbstractInsnMarker extends AbstractMarker {
abstract class AbstractInsnMarker extends AbstractMarker {