Commit ed524974 authored by Lubomir Bulej's avatar Lubomir Bulej

- Merged the new DiSL agent code. Code generations options are not yet used.

- Removed the old DiSL agent code as well as the old Java agent.
- Copied old shared DiSL agent headers to Shadow VM agent.
- Added JDK includes for JNI and JVMTI to avoid looking for them.
- Unified the naming of source directories.
- Updated the test infrastructure to the new build system layout.
- Examples can be now run even from the source distribution.
parent 307e662d
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="output/build/disl" path="src"/>
<classpathentry kind="src" output="output/build/shvm" path="src-re-server"/>
<classpathentry kind="src" output="output/build/disl" path="src-disl"/>
<classpathentry kind="src" output="output/build/shvm" path="src-shvm"/>
<classpathentry kind="src" output="output/build/util" path="src-util"/>
<classpathentry kind="src" output="output/build/test" path="src-test"/>
<classpathentry kind="src" output="output/build/shvm-dispatch" path="src-re-disp"/>
<classpathentry kind="src" output="output/build/disl-agent" path="src-agent-java"/>
<classpathentry kind="src" output="output/build/shvm-dispatch" path="src-shvm-dispatch"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="output/eclipse-dynamicbypass.jar"/>
<classpathentry kind="lib" path="output/lib/disl-bypass.jar"/>
<classpathentry kind="lib" path="lib/asm-debug-all-4.1.jar"/>
<classpathentry kind="lib" path="lib/hamcrest-core-1.3.jar"/>
<classpathentry kind="lib" path="lib/junit-4.11.jar"/>
......
......@@ -472,7 +472,7 @@ def run_client(args, parser):
cagent = args.disl_home+"/lib/libdislagent"+lib_suffix()
eagent = args.disl_home+"/lib/libdislreagent"+lib_suffix()
jagent = args.disl_home+"/lib/disl-agent.jar"
bypass = args.disl_home+"/lib/disl-bypass.jar"
dispatch = args.disl_home+"/lib/dislre-dispatch.jar"
c_cmd = ["java"]
......@@ -482,12 +482,10 @@ def run_client(args, parser):
if args.cse == True:
c_cmd+= ["-agentpath:"+eagent]
c_cmd+= ["-javaagent:"+jagent]
if args.cse == True:
c_cmd+= ["-Xbootclasspath/a:"+jagent+":"+args.instrumentation+":"+dispatch]
c_cmd+= ["-Xbootclasspath/a:"+bypass+":"+args.instrumentation+":"+dispatch]
else:
c_cmd+= ["-Xbootclasspath/a:"+jagent+":"+args.instrumentation]
c_cmd+= ["-Xbootclasspath/a:"+bypass+":"+args.instrumentation]
c_cmd+= args.c_app
......
......@@ -14,14 +14,12 @@ ant-contrib.path=${lib.dir}/${ant-contrib.lib}
src.bin=bin
src.disl=src
src.disl.bypass=src-dynbypass
src.disl.bypass.dynamic=src-dynbypass-act
src.disl.agent=src-agent-c
src.disl.agent.java=src-agent-java
src.shvm=src-re-server
src.shvm.dispatch=src-re-disp
src.shvm.agent=src-re-agent
src.disl=src-disl
src.disl.bypass=src-disl-bypass
src.disl.agent=src-disl-agent
src.shvm=src-shvm
src.shvm.agent=src-shvm-agent
src.shvm.dispatch=src-shvm-dispatch
src.test=src-test
src.util=src-util
src.doc=doc
......@@ -30,29 +28,52 @@ src.doc.intro=${src.doc}/intro
src.examples=examples
# Based output directory
out.dir=output
build=${out.dir}/build
build.util=${build}/util
build.disl=${build}/disl
# Directories for building artifacts
build.dir=${out.dir}/build
build.util=${build.dir}/util
build.disl=${build.dir}/disl
build.disl.thread=${build.disl}-thread
build.disl.bypass=${build.disl}-bypass
build.disl.agent.java=${build.disl}-agent
build.shvm=${build}/shvm
build.shvm=${build.dir}/shvm
build.shvm.dispatch=${build.shvm}-dispatch
build.test=${build}/test
build.test.jars=${build.test}-jars
build.doc=${build}/doc
build.doc.intro=${build.doc}-intro
dist=${out.dir}/dist
dist.bin=${dist}/bin
dist.lib=${dist}/lib
dist.doc=${dist}/doc
dist.doc.jdoc=${dist.doc}/javadoc
build.test=${build.dir}/test
build.doc.intro=${build.dir}/intro
# Directories for output artifacts
out.lib=${out.dir}/lib
out.src=${out.dir}/src
out.test=${out.dir}/test
out.doc.jdoc=${out.dir}/jdoc
# Output library artifact names
disl.lib=disl-server.jar
disl.bypass.lib=disl-bypass.jar
disl.agent.lib.base=dislagent
shvm.lib=dislre-server.jar
shvm.dispatch.lib=dislre-dispatch.jar
shvm.agent.lib.base=dislreagent
eclipse.agent.lib=eclipse-agent.jar
# Directories in distribution archives
dist.bin=bin
dist.lib=lib
dist.doc=doc
dist.doc.intro=${dist.doc}/intro
dist.examples=${dist}/examples
dist.doc.jdoc=${dist.doc}/javadoc
dist.examples=examples
dist.src=
# Directory for release archives
release=${out.dir}/release
release.bin.zip=${release}/disl-${disl.version}-bin.zip
release.bin.tar=${release}/disl-${disl.version}-bin.tar.bz2
......
This diff is collapsed.
disl.version=unspec
disl.version=devel
disl.prefix=disl-${disl.version}
......@@ -3,9 +3,9 @@
================================================================================
These examples demonstrate fthe basic features of DiSL. In addition, they
provide guidelines on how to package the instrumentation classes and how to run
the instrumented application using a simple launcher script that takes care of
starting the necessary Java virtual machines.
provide basic guidelines on how to package the instrumentation classes and how
to run the instrumented application using a simple launcher script that takes
care of starting the necessary Java virtual machines.
--------------------------------------------------------------------------------
......@@ -107,20 +107,19 @@ more details try running this example directly using "disl.py" and supplying
= HOW TO RUN THE EXAMPLES
================================================================================
If you have downloaded a binary DiSL distribution, enter the "examples"
directory. If you are using a source DiSL distribution, first compile DiSL by
running "ant" in the top-level directory (see README), then enter the
"output/dist/examples" directory.
If you are using a source DiSL distribution, first compile DiSL by running
"ant" in the top-level directory (see README). You can skip this step if you
are using a binary distribution of DiSL.
Choose an example you want to run, for example "smoke", and enter the
corresponding directory. To run the example, just execute "ant run".
In the "examples" directory, choose an example you want to run, e.g., "smoke",
enter the corresponding directory, and execute "ant run".
This command builds and packages the application and the instrumentation
classes and then, using the laucher script, starts the DiSL instrumentation
server and later on the application VM.
The output of the application and the applied instrumentation should be visible
on the console.
The output of the application as well as that of the applied instrumentation
should be visible on the console.
When compiled, the example can be also run using the "disl.py" launcher script
found in the "bin" directory, which allows specifying more options. To learn
......
<!--
This build file is intended to be included
from a build.xml file in each example directory.
-->
<project name="example">
<!--
This build file is intended to be included
from a build.xml file in each example directory.
-->
<property name="build.sysclasspath" value="ignore" />
<dirname property="examples.basedir" file="${ant.file.example}" />
<property file="${examples.basedir}/build-override.properties" />
<property file="${examples.basedir}/build.properties" />
<path id="inst.classpath">
<pathelement location="${examples.basedir}/${asm.path}" />
<pathelement location="${examples.basedir}/${disl.server.path}" />
<pathelement location="${examples.basedir}/${shvm.server.path}" />
<pathelement location="${examples.basedir}/${shvm.dispatch.path}" />
<pathelement location="${asm.path}" />
<pathelement location="${disl.server.path}" />
<pathelement location="${shvm.server.path}" />
<pathelement location="${shvm.dispatch.path}" />
</path>
<target name="init">
<mkdir dir="${build}" />
</target>
<target name="compile-app" depends="init">
<target name="build-app" description="Compiles and packages the application.">
<mkdir dir="${build.app}" />
<javac srcdir="${src.app}" destdir="${build.app}" debug="true" includeAntRuntime="false" />
</target>
<target name="package-app" depends="compile-app" description="Creates application package.">
<jar basedir="${build.app}" destfile="${build}/${app.jar.name}">
<jar destfile="${app.path}" basedir="${build.app}">
<manifest>
<attribute name="Main-Class" value="Main" />
</manifest>
</jar>
</target>
<target name="compile-inst" depends="init">
<target name="build-inst" description="Compiles and packages the instrumentation.">
<mkdir dir="${build.inst}" />
<javac srcdir="${src.inst}" destdir="${build.inst}" debug="true" includeAntRuntime="false">
<classpath refid="inst.classpath" />
</javac>
</target>
<target name="package-inst" depends="compile-inst" description="Creates instrumentation package.">
<jar basedir="${build.inst}" destfile="${build}/${inst.jar.name}" excludes="MANIFEST.MF" manifest="${src.inst}/MANIFEST.MF" />
<jar destfile="${inst.path}" basedir="${build.inst}" excludes="MANIFEST.MF" manifest="${src.inst}/MANIFEST.MF" />
</target>
<target name="build" depends="package-app,package-inst" />
<target name="build" depends="build-app,build-inst" />
<target name="run" depends="build">
<exec executable="${examples.basedir}/${bin.path}/disl.py">
<exec executable="${disl.launcher.path}">
<arg value="-d" />
<arg value="${disl.home}" />
<arg value="-cse" />
<!-- <arg value="-c_out=client.out" /> -->
<!-- <arg value="-e_out=evaluation.out" /> -->
<arg value="--" />
<arg value="${build}/${inst.jar.name}" />
<arg value="${inst.path}" />
<arg value="-jar" />
<arg value="${build}/${app.jar.name}" />
</exec>
<arg value="${app.path}" />
</exec>
</target>
<target name="clean">
<delete dir="${build}" />
<delete dir="${build.dir}" />
</target>
</project>
disl.home=${examples.basedir}/../output
bin.path=${examples.basedir}/../bin
disl.home=..
disl.home=${examples.basedir}/..
lib.path=${disl.home}/lib
bin.path=${disl.home}/bin
disl.launcher.path=${bin.path}/disl.py
disl.server.path=${lib.path}/disl-server.jar
shvm.server.path=${lib.path}/dislre-server.jar
shvm.dispatch.path=${lib.path}/dislre-dispatch.jar
asm.version=4.1
asm.path=${lib.path}/asm-debug-all-${asm.version}.jar
asm.path=${lib.path}/asm-debug-all-4.1.jar
src.app=src-app
src.inst=src-inst
build=build
build.app=${build}/app
build.inst=${build}/inst
build.dir=build
build.app=${build.dir}/app
build.inst=${build.dir}/inst
app.jar.name=example-app.jar
inst.jar.name=example-inst.jar
app.path=${build.dir}/example-app.jar
inst.path=${build.dir}/example-inst.jar
# if there is JAVA_HOME var file then include it
ifneq (, $(wildcard javahome/var))
include javahome/var
endif
# Source lists
LIBNAME=dislagent
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
JNI_OS=linux
else ifeq ($(UNAME), Darwin)
LIBRARY=lib$(LIBNAME).jnilib
JNI_OS=darwin
else
$(error error: unsupported operating system: $(UNAME))
endif
# Building a shared library
LINK_SHARED=$(LINK.c) -shared -o $@
# GNU Compiler options needed to build it
COMMON_FLAGS=-fPIC
# Options that help find errors
COMMON_FLAGS+= -W -Wall -Wextra -O3 -Wno-unused-parameter
CFLAGS += $(COMMON_FLAGS)
CFLAGS += -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/$(JNI_OS)
# add debugging output
ifeq ($(DEBUG), TRUE)
CFLAGS += -DDEBUG
endif
all: $(LIBRARY)
# Build native library
$(LIBRARY): $(OBJECTS)
$(LINK_SHARED) $(OBJECTS) $(LIBRARIES)
# Cleanup the built bits
clean:
rm -f $(LIBRARY) $(OBJECTS)
debug:
$(MAKE) DEBUG=TRUE
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <netinet/tcp.h>
#include <jvmti.h>
#include <jni.h>
// has to be defined for jvmtihelper.h
#define ERR_PREFIX "DiSL agent error: "
#include "jvmtihelper.h"
#include "comm.h"
#include "dislagent.h"
static const int ERR_SERVER = 10003;
// defaults - be sure that space in host_name is long enough
static const char * DEFAULT_HOST = "localhost";
static const char * DEFAULT_PORT = "11217";
typedef struct {
jint control_size;
jint classcode_size;
const unsigned char * control;
const unsigned char * classcode;
} message;
// linked list to hold socket file descriptor
// access must be protected by monitor
struct strc_connection_item {
int sockfd;
volatile int available;
struct strc_connection_item *next;
};
typedef struct strc_connection_item connection_item;
// port and name of the instrumentation server
static char host_name[1024];
static char port_number[6]; // including final 0
static jvmtiEnv * jvmti_env;
static jrawMonitorID global_lock;
// we are using multiple connections for parallelization
// pros: there is no need for synchronization in this client :)
// cons: gets ugly with strong parallelization
// the first element on the list of connections
// modifications should be protected by critical section
static connection_item * conn_list = NULL;
// ******************* Helper routines *******************
static message create_message(const unsigned char * control,
jint control_size, const unsigned char * classcode,
jint classcode_size) {
message result;
// control + size
result.control_size = control_size;
// contract: (if control_size <= 0) pointer may be copied (stolen)
if(control != NULL && control_size > 0) {
// without ending 0
unsigned char * buffcn = (unsigned char *) malloc(control_size);
memcpy(buffcn, control, control_size);
result.control = buffcn;
}
else {
result.control = control;
result.control_size = abs(control_size);
}
// class code + size
result.classcode_size = classcode_size;
// contract: (if classcode_size <= 0) pointer may be copied (stolen)
if(classcode != NULL && classcode_size > 0) {
unsigned char * buffcc = (unsigned char *) malloc(classcode_size);
memcpy(buffcc, classcode, classcode_size);
result.classcode = buffcc;
}
else {
result.classcode = classcode;
result.classcode_size = abs(classcode_size);
}
return result;
}
static void free_message(message * msg) {
if(msg->control != NULL) {
// cast because of const
free((void *) msg->control);
msg->control = NULL;
msg->control_size = 0;
}
if(msg->classcode != NULL) {
// cast because of const
free((void *) msg->classcode);
msg->classcode = NULL;
msg->classcode_size = 0;
}
}
static void parse_agent_options(char *options) {
static const char PORT_DELIM = ':';
// assign defaults
strcpy(host_name, DEFAULT_HOST);
strcpy(port_number, DEFAULT_PORT);
// no options found
if (options == NULL) {
return;
}
char * port_start = strchr(options, PORT_DELIM);
// process port number
if(port_start != NULL) {
// replace PORT_DELIM with end of the string (0)
port_start[0] = '\0';
// move one char forward to locate port number
++port_start;
// convert number
int fitsP = strlen(port_start) < sizeof(port_number);
check_error(! fitsP, "Port number is too long");
strcpy(port_number, port_start);
}
// check if host_name is big enough
int fitsH = strlen(options) < sizeof(host_name);
check_error(! fitsH, "Host name is too long");