Commit ece43616 authored by Vít Kabele's avatar Vít Kabele

Code cleanup

parent 0a52618e
Pipeline #4602 failed with stages
in 3 minutes and 51 seconds
......@@ -55,7 +55,6 @@
<src path="src/src-dislreserver" />
<src path="src/src-msg-analyze" />
<src path="src/src-msg-analyze-mtdispatch" />
<src path="src/src-msg-instr" />
<src path="src/src-proto" />
<src path="src/src-remoteanalysis" />
<src path="src/src-reqdispatch" />
......
......@@ -46,7 +46,7 @@ public abstract class DiSLREServer {
__log.debug ("server started");
__serverStarted ();
ISHVM server = new SHVM (__log);
SHVM server = new SHVMImpl (__log);
try {
final SocketChannel clientSocket = socket.accept ();
......@@ -86,18 +86,15 @@ public abstract class DiSLREServer {
* @param sock
* @param server
*/
private static void processRequests (final Socket sock, final ISHVM server) {
private static void processRequests (final Socket sock, final SHVM server)
{
try {
final DataInputStream is = new DataInputStream (
new BufferedInputStream (sock.getInputStream ()));
final DataOutputStream os = new DataOutputStream (
new BufferedOutputStream (sock.getOutputStream ()));
RequestDispatcher requestDispatcher = new RequestDispatcher (server);
Protocol.AgentMessage agentMessage;
int messageSize;
byte[] pole;
byte[] byteArray;
while (true) {
try {
......@@ -106,13 +103,13 @@ public abstract class DiSLREServer {
break;
}
pole = new byte[messageSize];
byteArray = new byte[messageSize];
is.readFully (pole,0, messageSize);
is.readFully (byteArray,0, messageSize);
agentMessage = Protocol.AgentMessage.parseFrom (pole);
agentMessage = Protocol.AgentMessage.parseFrom (byteArray);
requestDispatcher.ProcessMessage (agentMessage, __log);
RequestDispatcher.ProcessMessage (server, agentMessage, __log);
}
} catch (final Exception e) {
......
......@@ -8,45 +8,38 @@ import ch.usi.dag.util.logging.Logger;
* Request dispatcher will take the protocol buffer message and pass the data to appropriate method
* call.
*
* TODO: Consider making this class static, since it's only helper class with only one method.
*/
final class RequestDispatcher {
private final ISHVM __shadowVM;
RequestDispatcher(ISHVM shadowVM)
{
__shadowVM = shadowVM;
}
/**
* Process the agent message, and pass the unpacked data to {@link ISHVM} instance.
* Process the agent message, and pass the unpacked data to {@link SHVM} instance.
*
* @param agentMessage
* @param logger
* @param shadowVM ShadowVM instance to process the requests.
* @param agentMessage The agent message.
* @param logger Logger
* @throws DiSLREServerException
*/
void ProcessMessage(final AgentMessage agentMessage, final Logger logger)
throws DiSLREServerException
static void ProcessMessage(
final SHVM shadowVM, final AgentMessage agentMessage, final Logger logger
) throws DiSLREServerException
{
switch (agentMessage.getRequestCase ())
{
case ANALYZE:
Analyze analyze = agentMessage.getAnalyze ();
__shadowVM.HandleAnalyze (
shadowVM.HandleAnalyze (
analyze.getOrderingID (),
analyze.getInvocationCount (),
analyze.getRawData ().toByteArray ()
);
break;
case CLOSE:
__shadowVM.HandleClose ();
shadowVM.HandleClose ();
break;
case CLASS_INFO:
ClassInfo classInfo = agentMessage.getClassInfo ();
__shadowVM.HandleClassInfo (
shadowVM.HandleClassInfo (
classInfo.getClassTag (),
classInfo.getClassSignature (),
classInfo.getClassGeneric (),
......@@ -56,32 +49,32 @@ final class RequestDispatcher {
break;
case NEW_CLASS:
NewClass newClass = agentMessage.getNewClass ();
__shadowVM.HandleNewClass (
shadowVM.HandleNewClass (
newClass.getClassName (),
newClass.getClassLoaderTag (),
newClass.getClassData ().toByteArray ()
);
break;
case THREAD_END:
__shadowVM.HandleThreadEnd (agentMessage.getThreadEnd ().getThreadId ());
shadowVM.HandleThreadEnd (agentMessage.getThreadEnd ().getThreadId ());
break;
case REGISTER_ANALYSIS:
RegisterAnalysis registerAnalysis = agentMessage.getRegisterAnalysis ();
__shadowVM.HandleRegisterAnalysis (
shadowVM.HandleRegisterAnalysis (
registerAnalysis.getAnalysisId (),
registerAnalysis.getDescriptor ()
);
break;
case STRING_INFO:
StringInfo stringInfo = agentMessage.getStringInfo ();
__shadowVM.HandleStringInfo (
shadowVM.HandleStringInfo (
stringInfo.getStringTag (),
stringInfo.getStringData ()
);
break;
case THREAD_INFO:
ThreadInfo threadInfo = agentMessage.getThreadInfo ();
__shadowVM.HandleThreadInfo (
shadowVM.HandleThreadInfo (
threadInfo.getThreadTag (),
threadInfo.getName (),
threadInfo.getIsDaemon ()
......@@ -102,7 +95,7 @@ final class RequestDispatcher {
ids[i] = ByteArrayUtils.ReadLong (byteArray, i * Long.BYTES);
}
__shadowVM.HandleObjectFree (ids);
shadowVM.HandleObjectFree (ids);
break;
case REQUEST_NOT_SET:
default:
......
/**
* ISHVM implementation
* SHVM implementation
*
* Author: Vit Kabele <vit@kabele.me>
* Created on the 21/02/2019
......@@ -12,13 +12,13 @@ import ch.usi.dag.dislreserver.remoteanalysis.RemoteAnalysis;
import ch.usi.dag.util.logging.Logger;
/**
* Implementation of ISHVM.
* Implementation of SHVM.
*
* This class should represent the one re-usable class that will represent
* i.e. one analysis session. All the needed data including reflective information
* should be available in its instance.
*/
public class SHVM implements ISHVM {
public class SHVMImpl implements SHVM {
/**
* Logger instance
......@@ -43,7 +43,7 @@ public class SHVM implements ISHVM {
*
* @param logger
*/
SHVM (
SHVMImpl (
final Logger logger
) {
__log = logger;
......@@ -127,15 +127,15 @@ public class SHVM implements ISHVM {
* Register the new class loaded to the observed JVM.
*
* @param name Class name.
* @param tag Unique identifier of the class in the context of observed VM.
* @param loaderTag Unique identifier of the class in the context of observed VM.
* @param data Bytes with class code.
*/
@Override
public void HandleNewClass (String name, long tag, byte[] data)
public void HandleNewClass (String name, long loaderTag, byte[] data)
{
__shvmContext
.getShadowClassTable ()
.loadClass (name, tag, data);
.loadClass (name, loaderTag, data);
}
......@@ -164,7 +164,7 @@ public class SHVM implements ISHVM {
.getAnalysisResolver ()
.registerMethodId ((short)analysisID, descriptor);
__log.debug ("DiSL-RE: registered %s as analysis method %d\n", descriptor, analysisID);
__log.debug ("DiSL-RE: registered %s as analysis method %d\n", descriptor, analysisID);
}
......
package ch.usi.dag.dislreserver;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import ch.usi.dag.dislreserver.InstrMsgReader.InstrClassMessage;
public abstract class AbstractInstrumentation implements RequestHandler {
// used for replays
private static final byte[] emptyByteArray = new byte[0];
public void handle(DataInputStream is, DataOutputStream os, boolean debug)
throws DiSLREServerException {
try {
InstrClassMessage nm = InstrMsgReader.readMessage(is);
byte[] instrClass;
try {
instrClass = instrument(new String(nm.getControl()),
nm.getClassCode());
}
catch (DiSLREServerException e) {
// instrumentation error
// send the client a description of the server-side error
String errToReport = e.getMessage();
// during debug send the whole message
if(debug) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
errToReport = sw.toString();
}
// error protocol:
// control contains the description of the server-side error
// class code is an array of size zero
String errMsg = "Instrumentation error for class "
+ new String(nm.getControl()) + ": " + errToReport;
InstrMsgReader.sendMessage(os, new InstrClassMessage(errMsg
.getBytes(), emptyByteArray));
throw e;
}
InstrClassMessage replyData = null;
if(instrClass != null) {
// class was modified - send modified data
replyData = new InstrClassMessage(emptyByteArray, instrClass);
}
else {
// zero length means no modification
replyData = new InstrClassMessage(emptyByteArray, emptyByteArray);
}
InstrMsgReader.sendMessage(os, replyData);
}
catch (IOException e) {
throw new DiSLREServerException(e);
}
}
protected abstract byte[] instrument(String string, byte[] classCode)
throws DiSLREServerException;
}
package ch.usi.dag.dislreserver;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class InstrMsgReader {
public static class InstrClassMessage {
private byte[] control;
private byte[] classCode;
public InstrClassMessage(byte[] control, byte[] classCode) {
this.control = control;
this.classCode = classCode;
}
public byte[] getControl() {
return control;
}
public byte[] getClassCode() {
return classCode;
}
}
public static InstrClassMessage readMessage(DataInputStream is) throws IOException {
// protocol:
// java int - control string length (ctl)
// java int - class code length (ccl)
// bytes[ctl] - control string (contains class name)
// bytes[ccl] - class code
int controlLength = is.readInt();
int classCodeLength = is.readInt();
// allocate buffer for class reading
byte[] control = new byte[controlLength];
byte[] classCode = new byte[classCodeLength];
// read class
is.readFully(control);
is.readFully(classCode);
return new InstrClassMessage(control, classCode);
}
public static void sendMessage(DataOutputStream os, InstrClassMessage icm)
throws IOException {
// protocol:
// java int - control string (ctl)
// java int - class code length (ccl)
// bytes[ctl] - control string
// bytes[ccl] - class code
os.writeInt(icm.getControl().length);
os.writeInt(icm.getClassCode().length);
os.write(icm.getControl());
os.write(icm.getClassCode());
os.flush();
}
}
......@@ -13,7 +13,7 @@ package ch.usi.dag.dislreserver;
* rename those methods so that the Handle prefix will be omitted, because it's actually not handling
* any messages, but changing the inner state of ShadowVM object model.
*/
public interface ISHVM {
public interface SHVM {
/**
* Handle the message with data about some previously loaded class.
......@@ -45,10 +45,10 @@ public interface ISHVM {
* Handle the message about loading new class into observed VM.
*
* @param name Class name.
* @param tag Unique identifier of the class in the context of observed VM.
* @param loaderTag Unique identifier of the class in the context of observed VM.
* @param data Bytes with class code.
*/
void HandleNewClass(String name, long tag, byte[] data);
void HandleNewClass(String name, long loaderTag, byte[] data);
/**
* Handle the batch of object freeing messages.
......
......@@ -38,27 +38,20 @@ public final class ShadowClassTable {
static final AtomicReference <ShadowClass> JAVA_LANG_CLASS;
private static final Type __JAVA_LANG_CLASS_TYPE__;
private final Type __JAVA_LANG_CLASS_TYPE__;
private final SHVMContext __shvmContext;
private static final ConcurrentHashMap <Integer, ShadowClass> shadowClasses;
private final ConcurrentHashMap <Integer, ShadowClass> shadowClasses;
// TODO LB: Associate class code with class loader shadow objects.
private static final ConcurrentHashMap <ShadowObject, ConcurrentHashMap <Type, byte []>> classLoaderMap;
private final ConcurrentHashMap <ShadowObject, ConcurrentHashMap <Type, byte []>> classLoaderMap;
//
static {
JAVA_LANG_CLASS = new AtomicReference <> ();
__JAVA_LANG_CLASS_TYPE__ = Type.getType (Class.class);
shadowClasses = new ConcurrentHashMap <> (__INITIAL_SIZE__);
classLoaderMap = new ConcurrentHashMap <> (__INITIAL_SIZE__);
BOOTSTRAP_CLASSLOADER = new ShadowObject (0, null);
classLoaderMap.put (BOOTSTRAP_CLASSLOADER, new ConcurrentHashMap <> ());
}
/**
......@@ -67,8 +60,24 @@ public final class ShadowClassTable {
*/
public ShadowClassTable(final SHVMContext shvmContext){
__shvmContext = shvmContext;
__JAVA_LANG_CLASS_TYPE__ = Type.getType (Class.class);
shadowClasses = new ConcurrentHashMap <> (__INITIAL_SIZE__);
classLoaderMap = new ConcurrentHashMap <> (__INITIAL_SIZE__);
classLoaderMap.put (BOOTSTRAP_CLASSLOADER, new ConcurrentHashMap <> ());
}
/**
* Store the loaded class
*
* @param classInternalName
* @param classLoaderNetReference
* @param classCode
*/
public void loadClass (
final String classInternalName, final long classLoaderNetReference,
final byte [] classCode
......@@ -87,12 +96,12 @@ public final class ShadowClassTable {
}
/**
* Returns name of the classloader, or the default on if absent.
* Returns name of the classloader, or the default if absent.
*
* @param classLoader ClassLoader shadow object
* @return ShadowObject of classloader.
*/
private static ShadowObject __safeClassLoader (final ShadowObject classLoader) {
private ShadowObject __safeClassLoader (final ShadowObject classLoader) {
return (classLoader != null) ? classLoader : BOOTSTRAP_CLASSLOADER;
}
......@@ -238,6 +247,16 @@ public final class ShadowClassTable {
}
/**
* Fill the data to some previously loaded class.
* Register the instance of Java.lang.class
*
* @param netReference
* @param typeDescriptor
* @param classGenericStr
* @param classLoaderNetReference
* @param superclassNetReference
*/
public void registerClass (
final long netReference, final String typeDescriptor,
final String classGenericStr, final long classLoaderNetReference,
......
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