Commit 37cb40f9 authored by Lukáš Marek's avatar Lukáš Marek

Changed error reporting string for c-agent

parent 051498a6
......@@ -6,6 +6,14 @@
#include <unistd.h>
#include <netinet/tcp.h>
#if defined(__linux__)
# include <endian.h>
#elif defined(__FreeBSD__) || defined(__NetBSD__)
# include <sys/endian.h>
#elif defined(__APPLE__) && defined(__MACH__)
# include <machine/endian.h>
#endif
#include <jvmti.h>
#include <jni.h>
......@@ -15,7 +23,7 @@ static const int ERR_JVMTI = 10001;
static const int ERR_COMM = 10002;
static const int ERR_SERVER = 10003;
static const char * ERR_PREFIX = "ERROR in DiSL-RE agent: ";
static const char * ERR_PREFIX = "DiSL-RE agent error: ";
static const int TRUE = 1;
static const int FALSE = 0;
......@@ -24,6 +32,18 @@ static const int FALSE = 0;
static const char * DEFAULT_HOST = "localhost";
static const char * DEFAULT_PORT = "11218";
typedef struct {
unsigned char * buff;
size_t occupied;
size_t capacity;
} buffer;
// Messages - should be in sync with java server
// closing connection
static const jint MSG_CLOSE = 0;
static const jint MSG_ANALYZE = 1;
// port and name of the instrumentation server
static char host_name[1024];
static char port_number[6]; // including final 0
......@@ -35,11 +55,53 @@ static jrawMonitorID global_lock;
// access must be protected by monitor
static int connection = 0;
// Messages - should be in sync with java server
static buffer redispatch_buff;
// closing connection
static const jint MSG_CLOSE = 0;
static const jint MSG_ANALYZE = 1;
// ******************* Buffer routines *******************
void buffer_init(buffer * b) {
const size_t INIT_BUFF_SIZE = 1024;
b->buff = (unsigned char *) malloc(INIT_BUFF_SIZE);
b->capacity = INIT_BUFF_SIZE;
b->occupied = 0;
}
void buffer_fill(buffer * b, const void * data, size_t data_length) {
// not enough free space - extend buffer
if(b->capacity - b->occupied < data_length) {
unsigned char * old_buff = b->buff;
// alloc as much as needed to be able to insert data
size_t new_capacity = 2 * b->capacity;
while(new_capacity - b->occupied < data_length) {
new_capacity *= 2;
}
b->buff = (unsigned char *) malloc(new_capacity);
memcpy(b->buff, old_buff, b->occupied);
}
memcpy(b->buff + b->occupied, data, data_length);
b->occupied += data_length;
}
void buffer_clean(buffer * b) {
b->occupied = 0;
}
void buffer_free(buffer * b) {
free(b->buff);
b->buff = NULL;
b->capacity = 0;
b->occupied = 0;
}
// TODO unify in header - helper
// ******************* Helper routines *******************
......@@ -492,34 +554,118 @@ JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved)
connection = open_connection();
buffer_init(&redispatch_buff);
return 0;
}
// ******************* REDispatch helper methods *******************
// ******************* Sending helper methods *******************
// TODO if you add buffer as param it can server for other functions also
void send_int(jint to_send) {
// TODO should go to the buffer
void pack_boolean(buffer * buff, jboolean to_send) {
buffer_fill(buff, &to_send, sizeof(jboolean));
}
void pack_byte(buffer * buff, jbyte to_send) {
buffer_fill(buff, &to_send, sizeof(jbyte));
}
void pack_char(buffer * buff, jchar to_send) {
jchar nts = htons(to_send);
buffer_fill(buff, &nts, sizeof(jchar));
}
void pack_short(buffer * buff, jshort to_send) {
jshort nts = htons(to_send);
buffer_fill(buff, &nts, sizeof(jshort));
}
void pack_int(buffer * buff, jint to_send) {
jint nts = htonl(to_send);
send_data(connection, &nts, sizeof(jint));
buffer_fill(buff, &nts, sizeof(jint));
}
void pack_long(buffer * buff, jlong to_send) {
jlong nts = htobe64(to_send);
buffer_fill(buff, &nts, sizeof(jlong));
}
void pack_float(buffer * buff, jfloat to_send) {
jfloat nts = htonl(to_send);
buffer_fill(buff, &nts, sizeof(jfloat));
}
void pack_double(buffer * buff, jdouble to_send) {
jdouble nts = htobe64(to_send);
buffer_fill(buff, &nts, sizeof(jdouble));
}
void analysis_start(jint analysis_method_id) {
void pack_string_utf8(buffer * buff, const void * string_utf8,
uint16_t size_in_bytes) {
// send length first
uint16_t nsize = htons(size_in_bytes);
buffer_fill(buff, &nsize, sizeof(uint16_t));
buffer_fill(buff, string_utf8, size_in_bytes);
}
void pack_string_java(buffer * buff, jstring to_send, JNIEnv * jni_env) {
// get string length
jsize str_len = (*jni_env)->GetStringUTFLength(jni_env, to_send);
// get string data as utf-8
const char * str = (*jni_env)->GetStringUTFChars(jni_env, to_send, NULL);
check_std_error(str == NULL, TRUE, "Cannot get string from java");
// check if the size is sendable
int size_fits = str_len < UINT16_MAX;
check_std_error(size_fits, FALSE, "Java string is too big for sending");
// send string
pack_string_utf8(buff, str, str_len);
// release string
(*jni_env)->ReleaseStringUTFChars(jni_env, to_send, str);
}
void pack_object(buffer * buff, jobject to_send, JNIEnv * jni_env) {
// TODO
pack_int(buff, 0);
}
void pack_class(buffer * buff, jclass to_send, JNIEnv * jni_env) {
// TODO
pack_int(buff, 0);
}
// TODO should go to the buffer
void analysis_start(buffer * buff, jint analysis_method_id) {
// send analysis msg
send_int(MSG_ANALYZE);
pack_int(buff, MSG_ANALYZE);
// send method id
send_int(analysis_method_id);
pack_int(buff, analysis_method_id);
}
void analysis_end() {
void analysis_end(buffer * buff) {
// TODO should send the buffer with critical section
// TODO you can easily buffer messages
// - don't send buffer after flush but wait for other fushes
// - send remaining in shutdown
}
// ******************* REDispatch methods *******************
......@@ -527,67 +673,77 @@ void analysis_end() {
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_analysisStart
(JNIEnv * jni_env, jclass this_class, jint analysis_method_id) {
analysis_start(analysis_method_id);
analysis_start(&redispatch_buff, analysis_method_id);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_analysisEnd
(JNIEnv * jni_env, jclass this_class) {
analysis_end();
analysis_end(&redispatch_buff);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendBoolean
(JNIEnv * jni_env, jclass this_class, jboolean to_send) {
pack_boolean(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendByte
(JNIEnv * jni_env, jclass this_class, jbyte to_send) {
pack_byte(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendChar
(JNIEnv * jni_env, jclass this_class, jchar to_send) {
pack_char(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendShort
(JNIEnv * jni_env, jclass this_class, jshort to_send) {
pack_short(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendInt
(JNIEnv * jni_env, jclass this_class, jint to_send) {
send_int(to_send);
pack_int(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendLong
(JNIEnv * jni_env, jclass this_class, jlong to_send) {
pack_long(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendFloat
(JNIEnv * jni_env, jclass this_class, jfloat to_send) {
pack_float(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendDouble
(JNIEnv * jni_env, jclass this_class, jdouble to_send) {
pack_double(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendString
(JNIEnv * jni_env, jclass this_class, jstring to_send) {
pack_string_java(&redispatch_buff, to_send, jni_env);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendObject
(JNIEnv * jni_env, jclass this_class, jobject to_send) {
pack_object(&redispatch_buff, to_send, jni_env);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendClass
(JNIEnv * jni_env, jclass this_class, jclass to_send) {
pack_class(&redispatch_buff, to_send, jni_env);
}
......@@ -45,7 +45,11 @@ public abstract class DiSLREServer {
System.out.println("DiSL-RE server is shutting down");
}
} catch (Exception e) {
}
catch (IOException e) {
reportError(new DiSLREServerException(e));
}
catch (Throwable e) {
reportError(e);
}
}
......@@ -73,19 +77,33 @@ public abstract class DiSLREServer {
}
}
private static void reportInnerError(Throwable e) {
Throwable cause = e.getCause();
while (cause != null) {
System.err.println(" Inner error: " + cause.getMessage());
cause = cause.getCause();
}
}
private static void reportError(Throwable e) {
if (e instanceof DiSLREServerException) {
System.err.println("DiSL-RE server error: " + e.getMessage());
reportInnerError(e);
if (debug) {
e.printStackTrace();
}
return;
}
// fatal exception (unexpected)
System.err.println("Fatal error: " + e.getMessage());
System.err.println("DiSL-RE fatal error: " + e.getMessage());
e.printStackTrace();
}
......
......@@ -3,7 +3,6 @@ package ch.usi.dag.dislreserver.msg.analyze;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
......@@ -63,15 +62,22 @@ public class AnalysisHandler implements RequestHandler {
}
// *** invoke method ***
analysisMethod.invoke(amh.getAnalysisInstance(), args.toArray());
try {
// TODO re - support static methods
analysisMethod.invoke(amh.getAnalysisInstance(), args.toArray());
}
catch(Exception e) {
System.err.println("DiSL-RE analysis exception: "
+ e.getMessage());
e.printStackTrace();
}
} catch (IOException e) {
throw new DiSLREServerException(e);
} catch (IllegalAccessException e) {
throw new DiSLREServerException(e);
} catch (IllegalArgumentException e) {
}
catch (IOException e) {
throw new DiSLREServerException(e);
} catch (InvocationTargetException e) {
}
catch (IllegalArgumentException e) {
throw new DiSLREServerException(e);
}
}
......@@ -111,18 +117,8 @@ public class AnalysisHandler implements RequestHandler {
return is.readDouble();
}
// read string
if(argClass.equals(String.class)) {
// read the length of the string
int stringLength = is.readInt();
// read the string bytes
byte byteBuffer[] = new byte[stringLength];
is.readFully(byteBuffer);
// return string
return new String(byteBuffer);
return is.readUTF();
}
// read id only
......
......@@ -69,9 +69,19 @@ public class AnalysisResolver {
// TODO re - should not be hardcoded
try {
Method m = CodeExecuted.class.getMethod("bytecodesExecuted", int.class);
Object i = CodeExecuted.class.newInstance();
registerMethod(1, new AnalysisMethodHolder((RemoteAnalysis)i, m));
Method m1 = CodeExecuted.class.getMethod("bytecodesExecuted", int.class);
registerMethod(1, new AnalysisMethodHolder((RemoteAnalysis)i, m1));
Method m2 = CodeExecuted.class.getMethod("testingBasic",
boolean.class, byte.class, char.class, short.class,
int.class, long.class, float.class, double.class);
registerMethod(2, new AnalysisMethodHolder((RemoteAnalysis)i, m2));
Method m3 = CodeExecuted.class.getMethod("testingAdvanced",
String.class, Object.class, Class.class, int.class);
registerMethod(3, new AnalysisMethodHolder((RemoteAnalysis)i, m3));
} catch (Exception e) {
e.printStackTrace();
......
package ch.usi.dag.disl.test.dispatch;
import ch.usi.dag.dislreserver.objectid.InvalidClass;
import ch.usi.dag.dislreserver.objectid.ObjectId;
import ch.usi.dag.dislreserver.remoteanalysis.RemoteAnalysis;
// NOTE that this class is not static anymore
......@@ -11,6 +13,60 @@ public class CodeExecuted extends RemoteAnalysis {
totalExecutedBytecodes += count;
}
public void testingBasic(boolean b, byte by, char c, short s, int i, long l,
float f, double d) {
if(b != true) {
throw new RuntimeException("Incorect transfer of boolean");
}
if(by != (byte) 125) {
throw new RuntimeException("Incorect transfer of byte");
}
if(c != 'š') {
throw new RuntimeException("Incorect transfer of char");
}
if(s != (short) 50000) {
throw new RuntimeException("Incorect transfer of short");
}
if(i != 100000) {
throw new RuntimeException("Incorect transfer of int");
}
if(l != 10000000000L) {
throw new RuntimeException("Incorect transfer of long");
}
if(f != 1.5F) {
throw new RuntimeException("Incorect transfer of float");
}
if(d != 2.5) {
throw new RuntimeException("Incorect transfer of double");
}
}
public static void testingAdvanced(String s, Object o, Class<?> c,
int classID) {
if(! s.equals("ěščřžýáíé")) {
throw new RuntimeException("Incorect transfer of String");
}
// note that id will be 0 if this is first transfer of Object
if(! (o instanceof ObjectId) || ((ObjectId)o).getId() != 0) {
throw new RuntimeException("Incorect transfer of Object");
}
// note that id will be 0 if this is first transfer of Class
if(! c.equals(InvalidClass.class) || classID != 0) {
throw new RuntimeException("Incorect transfer of Class");
}
}
public void atExit() {
System.out.println("Total number of executed bytecodes: "
+ totalExecutedBytecodes);
......
......@@ -10,8 +10,40 @@ import ch.usi.dag.dislre.REDispatch;
public class CodeExecutedRE {
public static void bytecodesExecuted(int count) {
REDispatch.analysisStart(1);
REDispatch.sendInt(count);
REDispatch.analysisEnd();
}
public static void testingBasic(boolean b, byte by, char c, short s, int i,
long l, float f, double d) {
REDispatch.analysisStart(2);
REDispatch.sendBoolean(b);
REDispatch.sendByte(by);
REDispatch.sendChar(c);
REDispatch.sendShort(s);
REDispatch.sendInt(i);
REDispatch.sendLong(l);
REDispatch.sendFloat(f);
REDispatch.sendDouble(d);
REDispatch.analysisEnd();
}
public static void testingAdvanced(String s, Object o, Class<?> c, int classID) {
REDispatch.analysisStart(3);
REDispatch.sendString(s);
REDispatch.sendObject(o);
REDispatch.sendClass(c);
// class_id ignored
REDispatch.analysisEnd();
}
}
......@@ -2,11 +2,22 @@ package ch.usi.dag.disl.test.dispatch;
import ch.usi.dag.disl.annotation.After;
import ch.usi.dag.disl.marker.BasicBlockMarker;
import ch.usi.dag.disl.marker.BodyMarker;
public class DiSLClass {
@After(marker = BasicBlockMarker.class, scope = "TargetClass.*")
public static void invokedInstr(CodeLengthSC clsc) {
CodeExecutedRE.bytecodesExecuted(clsc.codeSize());
}
@After(marker = BodyMarker.class, scope = "TargetClass.main()")
public static void testing() {
CodeExecutedRE.testingBasic(true, (byte) 125, 'š', (short) 50000,
100000, 10000000000L, 1.5F, 2.5);
CodeExecutedRE.testingAdvanced("ěščřžýáíé", new Object(), Object.class, 0);
}
}
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