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 @@ ...@@ -6,7 +6,7 @@
<classpathentry kind="src" path="src-agent-java"/> <classpathentry kind="src" path="src-agent-java"/>
<classpathentry kind="src" path="src-test"/> <classpathentry kind="src" path="src-test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <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="build/eclipse-dynamicbypass.jar"/>
<classpathentry kind="lib" path="lib/asm-debug-all-4.1.jar"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>
DiSL DiSL
==== ====
DiSL is inspired by AOP, but in contrast to mainstream AOP languages, it features DiSL is a Java bytecode instrumentation framework intended for observation
an open join point model where any region of bytecodes can be selected as a join of programs executing in the Java Virtual Machine. It has been mainly used
point (i.e., code location to be instrumented). DiSL reconciles high-level for development of dynamic program analysis instrumentations, but it can be
language constructs resulting in concise instrumentations, high expressiveness, used equally well to develop instrumentations for, e.g. runtime performance
and efficiency of the inserted instrumentation code. Thanks to the monitoring, or other tasks not bent on altering program execution.
pointcut/advice model adopted by DiSL, instrumentations are similarly compact as
aspects written in AspectJ. However, in contrast to AspectJ, DiSL does not DiSL is inspired by AOP, but in contrast to mainstream AOP languages, it
restrict the code locations that can be instrumented, and the code generated by features an open join point model where any region of bytecodes can serve as
DiSL avoids expensive operations (such as object allocations that are not visible a join point (i.e., code location to be instrumented). DiSL also reconciles
to the programmer). Furthermore, DiSL supports instrumentations with complete high-level language concepts, such as the pointcut/advice programming model
bytecode coverage out-of-the-box and avoids structural modifications of classes found in AOP, with high expressiveness, and efficiency of bytecode
that would be visible through reflection and could break the instrumented code. 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/ link: http://forge.ow2.org/projects/disl/
INSTALL 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 EXAMPLES
======== ========
...@@ -31,13 +55,15 @@ EXAMPLES ...@@ -31,13 +55,15 @@ EXAMPLES
For the basic instrumentation example, please look in the example directory. For the basic instrumentation example, please look in the example directory.
Also the src-test directory contains simple examples of DiSL features. Also the src-test directory contains simple examples of DiSL features.
DOCUMENTATION DOCUMENTATION
============= =============
Please look at http://disl.projects.ow2.org/xwiki/bin/view/Main/Doc. Please look at http://disl.projects.ow2.org/xwiki/bin/view/Main/Doc.
USER ERRORS 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. 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} asm.path=lib/${asm.lib}
src.disl=src src.disl=src
......
...@@ -176,6 +176,10 @@ ...@@ -176,6 +176,10 @@
</target> </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 *** --> <!-- *** test instrumentaion package *** -->
<target name="check-test-property"> <target name="check-test-property">
......
disl.version=unspec disl.version=unspec
\ No newline at end of file
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: ...@@ -17,7 +17,7 @@ follow the steps:
1) compile application calling "ant" in the app directory 1) compile application calling "ant" in the app directory
2) compile instrumentation calling "ant" in the instrumentation 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 The last command starts the application together with DiSL. The output of the
application and the applied instrumentation should be visible on command line. application and the applied instrumentation should be visible on command line.
......
...@@ -11,13 +11,17 @@ SOURCES=dislagent.c ...@@ -11,13 +11,17 @@ SOURCES=dislagent.c
# Object files needed to create library # Object files needed to create library
OBJECTS=$(SOURCES:%.c=%.o) OBJECTS=$(SOURCES:%.c=%.o)
# Library name and options needed to build it # Library name and options needed to build it
UNAME := $(shell uname) UNAME := $(shell uname)
ifeq ($(UNAME), Linux) ifeq ($(UNAME), Linux)
LIBRARY=lib$(LIBNAME).so LIBRARY=lib$(LIBNAME).so
endif JNI_OS=linux
ifeq ($(UNAME), Darwin) else ifeq ($(UNAME), Darwin)
LIBRARY=lib$(LIBNAME).jnilib LIBRARY=lib$(LIBNAME).jnilib
JNI_OS=darwin
else
$(error error: unsupported operating system: $(UNAME))
endif endif
...@@ -31,7 +35,7 @@ COMMON_FLAGS+= -W -Wall -Wextra -O3 -Wno-unused-parameter ...@@ -31,7 +35,7 @@ COMMON_FLAGS+= -W -Wall -Wextra -O3 -Wno-unused-parameter
CFLAGS += $(COMMON_FLAGS) 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 # add debugging output
ifeq ($(DEBUG), TRUE) ifeq ($(DEBUG), TRUE)
...@@ -52,4 +56,4 @@ clean: ...@@ -52,4 +56,4 @@ clean:
debug: debug:
$(MAKE) DEBUG=TRUE $(MAKE) DEBUG=TRUE
all: build all: build
\ No newline at end of file
# rename this file to Makefile.local to take effect # rename this file to Makefile.local to take effect
# if variable is not defined autodetection or default is used # JAVA_HOME variable should be properly defined
#JAVA_HOME = /etc/alternatives/java_sdk/
# 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; ...@@ -54,7 +54,7 @@ import ch.usi.dag.disl.weaver.Weaver;
// TODO javadoc comment all // TODO javadoc comment all
/** /**
* Main DiSL class providing interface for an instrumentation framework * Main DiSL class providing interface for an instrumentation framework
* (normally DiSL Server) * (normally DiSL Server).
*/ */
public class DiSL { public class DiSL {
...@@ -85,7 +85,7 @@ public class DiSL { ...@@ -85,7 +85,7 @@ public class DiSL {
private final List<Snippet> snippets; private final List<Snippet> snippets;
/** /**
* DiSL initialization * DiSL initialization.
* @param useDynamicBypass enable or disable dynamic bypass instrumentation * @param useDynamicBypass enable or disable dynamic bypass instrumentation
*/ */
// this method should be called only once // this method should be called only once
...@@ -477,7 +477,7 @@ public class DiSL { ...@@ -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 * @param classAsBytes class as array of bytes
* @return instrumented class as array of bytes * @return instrumented class as array of bytes
...@@ -586,7 +586,7 @@ public class DiSL { ...@@ -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() { public void terminate() {
......
...@@ -6,15 +6,17 @@ import ch.usi.dag.disl.marker.Marker; ...@@ -6,15 +6,17 @@ import ch.usi.dag.disl.marker.Marker;
* The After annotation instructs DiSL to insert the snippet body after the * 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 * marked region. The snippet will be invoked after a normal exit of the region
* or after an exit caused by an exception. * or after an exit caused by an exception.
* * <br>
* <br>
* NOTE: This is only general contract. It depends on particular marker how the * NOTE: This is only general contract. It depends on particular marker how the
* contract will be implemented. * contract will be implemented.
* * <br>
* <br>
* This annotation should be used with methods. * This annotation should be used with methods.
* * <br>
* The method should be static, not return any values and not throw any * The method should be static, not return any values and not throw any
* exceptions. * exceptions.
* * <br>
* Method argument can be StaticContext, DynamicContext, ClassContext and * Method argument can be StaticContext, DynamicContext, ClassContext and
* ArgumentProcessorContext. * ArgumentProcessorContext.
*/ */
...@@ -33,44 +35,44 @@ public @interface After { ...@@ -33,44 +35,44 @@ public @interface After {
/** /**
* Argument for the marker (as string). * Argument for the marker (as string).
* * <br>
* Default value: "" * <br>
* Default value means none.
*/ */
String args() default ""; // cannot be null :( String args() default ""; // cannot be null :(
/** /**
* Scope of the methods, where the snippet is applied. * Scope of the methods, where the snippet is applied.
* * <br>
* @see ch.usi.dag.disl.scope package for more info about scoping language. * <br>
* * Default value means everything.
* Default value: "*" * <br>
* @see ch.usi.dag.disl.scope.ScopeImpl ScopeImpl for more info about
* scoping language.
*/ */
String scope() default "*"; String scope() default "*";
/** /**
* The guard class defining if the snippet will be inlined in particular * The guard class defining if the snippet will be inlined in particular
* region or not. * region or not.
* * <br>
* Default value: Object.class - means none * <br>
* Default value means none.
*/ */
Class<? extends Object> guard() default Object.class; // cannot be null :( Class<? extends Object> guard() default Object.class; // cannot be null :(
/** /**
* Defines ordering of the snippets. Smaller number indicates that snippet * Defines ordering of the snippets. Smaller number indicates that snippet
* will be inlined closer to the instrumented code. * will be inlined closer to the instrumented code.
*
* Default value: 100
*/ */
int order() default 100; int order() default 100;
/** /**
* Advanced option. You can in general disable dynamic bypass on snippets, * You can in general disable dynamic bypass on snippets, that are not using
* that are not using any other class. * any other class. (Advanced option)
* * <br>
* NOTE Usage of dynamic bypass is determined by the underlying * NOTE: Usage of dynamic bypass is determined by the underlying
* instrumentation framework. * instrumentation framework.
*
* Default value: true
*/ */
boolean dynamicBypass() default true; boolean dynamicBypass() default true;
} }
...@@ -6,15 +6,17 @@ import ch.usi.dag.disl.marker.Marker; ...@@ -6,15 +6,17 @@ import ch.usi.dag.disl.marker.Marker;
* The AfterReturning annotation instructs DiSL to insert the snippet body after * 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 * the marked region. The snippet will be invoked after a normal exit of the
* region. * region.
* * <br>
* <br>
* NOTE: This is only general contract. It depends on particular marker how the * NOTE: This is only general contract. It depends on particular marker how the
* contract will be implemented. * contract will be implemented.
* * <br>
* <br>
* This annotation should be used with methods. * This annotation should be used with methods.
* * <br>
* The method should be static, not return any values and not throw any * The method should be static, not return any values and not throw any
* exceptions. * exceptions.
* * <br>
* Method argument can be StaticContext, DynamicContext, ClassContext and * Method argument can be StaticContext, DynamicContext, ClassContext and
* ArgumentProcessorContext. * ArgumentProcessorContext.
*/ */
...@@ -25,7 +27,7 @@ public @interface AfterReturning { ...@@ -25,7 +27,7 @@ public @interface AfterReturning {
// NOTE because of implementation of annotations in java the defaults // NOTE because of implementation of annotations in java the defaults
// are not retrieved from here but from class mentioned above // are not retrieved from here but from class mentioned above
/** /**
* Marker class defines a region where the snippet is applied. * Marker class defines a region where the snippet is applied.
*/ */
...@@ -33,44 +35,44 @@ public @interface AfterReturning { ...@@ -33,44 +35,44 @@ public @interface AfterReturning {
/** /**
* Argument for the marker (as string). * Argument for the marker (as string).
* * <br>
* Default value: "" * <br>
* Default value means none.
*/ */
String args() default ""; // cannot be null :( String args() default ""; // cannot be null :(
/** /**
* Scope of the methods, where the snippet is applied. * Scope of the methods, where the snippet is applied.
* * <br>
* @see ch.usi.dag.disl.scope package for more info about scoping language. * <br>
* * Default value means everything.
* Default value: "*" * <br>
* @see ch.usi.dag.disl.scope.ScopeImpl ScopeImpl for more info about
* scoping language.
*/ */
String scope() default "*"; String scope() default "*";
/** /**
* The guard class defining if the snippet will be inlined in particular * The guard class defining if the snippet will be inlined in particular
* region or not. * region or not.
* * <br>
* Default value: Object.class - means none * <br>
* Default value means none.
*/ */
Class<? extends Object> guard() default Object.class; // cannot be null :( Class<? extends Object> guard() default Object.class; // cannot be null :(
/** /**
* Defines ordering of the snippets. Smaller number indicates that snippet * Defines ordering of the snippets. Smaller number indicates that snippet
* will be inlined closer to the instrumented code. * will be inlined closer to the instrumented code.
*
* Default value: 100
*/ */
int order() default 100; int order() default 100;
/** /**
* Advanced option. You can in general disable dynamic bypass on snippets, * You can in general disable dynamic bypass on snippets, that are not using
* that are not using any other class. * any other class. (Advanced option)
* * <br>
* NOTE Usage of dynamic bypass is determined by the underlying * NOTE: Usage of dynamic bypass is determined by the underlying
* instrumentation framework. * instrumentation framework.
*
* Default value: true
*/ */
boolean dynamicBypass() default true; boolean dynamicBypass() default true;
} }
...@@ -6,15 +6,17 @@ import ch.usi.dag.disl.marker.Marker; ...@@ -6,15 +6,17 @@ import ch.usi.dag.disl.marker.Marker;
* The AfterThrowing annotation instructs DiSL to insert the snippet body after * 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 * the marked region. The snippet will be invoked after an exit caused by an
* exception. * exception.
* * <br>
* <br>
* NOTE: This is only general contract. It depends on particular marker how the * NOTE: This is only general contract. It depends on particular marker how the
* contract will be implemented. * contract will be implemented.
* * <br>
* <br>
* This annotation should be used with methods. * This annotation should be used with methods.
* * <br>
* The method should be static, not return any values and not throw any * The method should be static, not return any values and not throw any
* exceptions. * exceptions.
* * <br>
* Method argument can be StaticContext, DynamicContext, ClassContext and * Method argument can be StaticContext, DynamicContext, ClassContext and
* ArgumentProcessorContext. * ArgumentProcessorContext.
*/ */
...@@ -25,7 +27,7 @@ public @interface AfterThrowing { ...@@ -25,7 +27,7 @@ public @interface AfterThrowing {
// NOTE because of implementation of annotations in java the defaults // NOTE because of implementation of annotations in java the defaults
// are not retrieved from here but from class mentioned above // are not retrieved from here but from class mentioned above
/** /**
* Marker class defines a region where the snippet is applied. * Marker class defines a region where the snippet is applied.
*/ */
...@@ -33,44 +35,44 @@ public @interface AfterThrowing { ...@@ -33,44 +35,44 @@ public @interface AfterThrowing {
/** /**
* Argument for the marker (as string). * Argument for the marker (as string).
* * <br>
* Default value: "" * <br>
* Default value means none.
*/ */
String args() default ""; // cannot be null :( String args() default ""; // cannot be null :(
/** /**
* Scope of the methods, where the snippet is applied. * Scope of the methods, where the snippet is applied.
* * <br>
* @see ch.usi.dag.disl.scope package for more info about scoping language. * <br>
* * Default value means everything.
* Default value: "*" * <br>
* @see ch.usi.dag.disl.scope.ScopeImpl ScopeImpl for more info about
* scoping language.
*/ */
String scope() default "*"; String scope() default "*";
/** /**
* The guard class defining if the snippet will be inlined in particular * The guard class defining if the snippet will be inlined in particular
* region or not. * region or not.
* * <br>
* Default value: Object.class - means none * <br>
* Default value means none.
*/ */
Class<? extends Object> guard() default Object.class; // cannot be null :( Class<? extends Object> guard() default Object.class; // cannot be null :(
/** /**
* Defines ordering of the snippets. Smaller number indicates that snippet * Defines ordering of the snippets. Smaller number indicates that snippet
* will be inlined closer to the instrumented code. * will be inlined closer to the instrumented code.
*
* Default value: 100
*/ */
int order() default 100; int order() default 100;
/** /**
* Advanced option. You can in general disable dynamic bypass on snippets, * You can in general disable dynamic bypass on snippets, that are not using
* that are not using any other class. * any other class. (Advanced option)
* * <br>
* NOTE Usage of dynamic bypass is determined by the underlying * NOTE: Usage of dynamic bypass is determined by the underlying
* instrumentation framework. * instrumentation framework.
*
* Default value: true
*/ */
boolean dynamicBypass() default true; boolean dynamicBypass() default true;
} }
...@@ -3,19 +3,20 @@ package ch.usi.dag.disl.annotation; ...@@ -3,19 +3,20 @@ package ch.usi.dag.disl.annotation;
/** /**
* Annotated class defines method for processing method arguments. The specified * Annotated class defines method for processing method arguments. The specified
* methods will be inlined into snippets to process one method argument value. * 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. * 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 * The allowed types are all basic types, String and Object class. The processed
* type can be extend in some special cases by ProcessAlso annotation. * type can be extend in some special cases by ProcessAlso annotation.
* During run-time, the argument will contain a processed method argument value. * During run-time, the argument will contain a processed method argument value.
*
* ArgumentContext can be used to fetch additional data about the argument. * ArgumentContext can be used to fetch additional data about the argument.
* * <br>
* <br>
* This annotation should be used with classes. * This annotation should be used with classes.
* * <br>
* The method should be static, not return any values and not throw any * The method should be static, not return any values and not throw any
* exceptions. * exceptions.
* * <br>
* Method argument can be StaticContext, DynamicContext, ClassContext and * Method argument can be StaticContext, DynamicContext, ClassContext and
* ArgumentContext. * ArgumentContext.
*/ */
......
...@@ -5,15 +5,17 @@ import ch.usi.dag.disl.marker.Marker; ...@@ -5,15 +5,17 @@ import ch.usi.dag.disl.marker.Marker;
/** /**
* The Before annotation instructs DiSL to insert the snippet body before the * 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. * 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 * NOTE: This is only general contract. It depends on particular marker how the
* contract will be implemented. * contract will be implemented.
* * <br>
* <br>
* This annotation should be used with methods. * This annotation should be used with methods.
* * <br>
* The method should be static, not return any values and not throw any * The method should be static, not return any values and not throw any
* exceptions. * exceptions.
* * <br>
* Method argument can be StaticContext, DynamicContext, ClassContext and * Method argument can be StaticContext, DynamicContext, ClassContext and
* ArgumentProcessorContext. * ArgumentProcessorContext.
*/ */
...@@ -24,7 +26,7 @@ public @interface Before { ...@@ -24,7 +26,7 @@ public @interface Before {
// NOTE because of implementation of annotations in java the defaults // NOTE because of implementation of annotations in java the defaults
// are not retrieved from here but from class mentioned above // are not retrieved from here but from class mentioned above
/** /**
* Marker class defines a region where the snippet is applied. * Marker class defines a region where the snippet is applied.
*/ */
...@@ -32,44 +34,44 @@ public @interface Before { ...@@ -32,44 +34,44 @@ public @interface Before {
/** /**
* Argument for the marker (as string).