Rename project

This commit is contained in:
Martin Hare Robertson 2010-04-06 00:32:38 +01:00
parent 04c75566c0
commit 88e5f63ab9
92 changed files with 3062 additions and 5 deletions

View File

@ -1,5 +0,0 @@
Manifest-Version: 1.0
Premain-Class: gb.instrument.agent.Agent
Agent-Class: gb.instrument.agent.Agent
Can-Redefine-Classes: true

10
org.intrace/.classpath Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="lib" path="lib/asm-2.2.3.jar"/>
<classpathentry kind="lib" path="lib/asm-commons-2.2.3.jar"/>
<classpathentry kind="lib" path="C:/Program Files/Java/jdk1.6.0/lib/tools.jar"/>
<classpathentry kind="con" path="SWT_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>

19
org.intrace/.project Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.intrace</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.jem.beaninfo.BeanInfoNature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,12 @@
#Thu Nov 05 12:58:44 GMT 2009
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

64
org.intrace/build.xml Normal file
View File

@ -0,0 +1,64 @@
<project name="TraceAgent" basedir="." default="help">
<target name="help">
<java classname="org.apache.tools.ant.Main">
<arg value="-projecthelp" />
</java>
</target>
<target name="build" depends="buildClasses, createJar, deploy" />
<target name="buildClasses" description="Comile classes">
<delete dir="./bin" includes="**/*" />
<mkdir dir="./bin" />
<javac srcdir="./src" destdir="./bin" debug="true" source="1.6" target="1.6" nowarn="true">
<classpath>
<fileset dir="./lib" includes="*.jar" erroronmissingdir="false" />
</classpath>
</javac>
</target>
<target name="createJar" description="Create the Agent Jar">
<delete dir="./lib/libclasses" includes="**/*" />
<mkdir dir="./lib/libclasses" />
<unzip src="./lib/asm-2.2.3.jar" dest="./lib/libclasses">
<patternset>
<include name="**/*.class" />
<exclude name="META-INF" />
</patternset>
</unzip>
<unzip src="./lib/asm-commons-2.2.3.jar" dest="./lib/libclasses">
<patternset>
<include name="**/EmptyVisitor.class" />
<exclude name="META-INF" />
</patternset>
</unzip>
<mkdir dir="./built/" />
<jar destfile="./built/traceagent.jar" compress="false" manifest="conf/META-INF/MANIFEST.MF">
<fileset dir="./bin" includes="**/agent/**/*.class" />
<fileset dir="./bin" includes="**/output/**/*.class" />
<fileset dir="./lib/libclasses" includes="**/*.class" />
</jar>
<jar destfile="./built/cuitraceclient.jar" compress="false">
<fileset dir="./bin" includes="**/output/trace/TraceConfigConstants.class" />
<fileset dir="./bin" includes="**/agent/AgentConfigConstants.class" />
<fileset dir="./bin" includes="**/client/cui/**/*.class" />
</jar>
<jar destfile="./built/guitraceclient.jar" filesetmanifest="mergewithoutmain">
<manifest>
<attribute name="Main-Class" value="gb.instrument.client.gui.TraceClient" />
<attribute name="Class-Path" value="." />
</manifest>
<fileset dir="./bin" includes="**/output/trace/TraceSettingsConstants.class" />
<fileset dir="./bin" includes="**/agent/AgentConfigConstants.class" />
<fileset dir="./bin" includes="**/client/gui/**/*.class" />
<zipfileset excludes="META-INF/*.SF" src="lib/org.eclipse.swt.win32.win32.x86_3.5.2.v3557f.jar" />
</jar>
<delete dir="./lib/libclasses" includes="**/*" />
</target>
<target name="deploy" description="Copy agent jar to another project">
<copy file="./built/traceagent.jar" tofile="../TestProject/lib/traceagent.jar" overwrite="true" />
</target>
</project>

View File

@ -0,0 +1,5 @@
Manifest-Version: 1.0
Premain-Class: org.intrace.agent.Agent
Agent-Class: org.intrace.agent.Agent
Can-Redefine-Classes: true

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,58 @@
package org.intrace.agent;
import java.io.IOException;
import java.lang.instrument.Instrumentation;
import org.intrace.agent.server.AgentServer;
/**
* Trace Agent: Installs a Class Transformer to add trace lines.
*/
public class Agent
{
/**
* Agent called on JVM init.
* @param agentArgs
* @param inst
* @throws IOException
*/
public static void premain(String agentArgs, Instrumentation inst) throws IOException
{
initialize(agentArgs, inst);
}
/**
* Agent called after JVM init.
* @param agentArgs
* @param inst
* @throws IOException
*/
public static void agentmain(String agentArgs, Instrumentation inst) throws IOException
{
initialize(agentArgs, inst);
}
/**
* Common init function.
* @param agentArgs
* @param inst
* @throws IOException
*/
private static void initialize(String agentArgs, Instrumentation inst) throws IOException
{
System.out.println("Loaded Tracing Agent.");
AgentSettings args = new AgentSettings(agentArgs);
AgentHelper.getActiveOutputHandler().getResponse(agentArgs);
ClassTransformer t = new ClassTransformer(inst, args);
inst.addTransformer(t, true);
t.traceLoadedClasses();
Thread traceServer = new Thread(new AgentServer(t));
traceServer.setName("TraceServer");
traceServer.setDaemon(true);
traceServer.start();
}
}

View File

@ -0,0 +1,10 @@
package org.intrace.agent;
public class AgentConfigConstants
{
public static final String CLASS_REGEX = "AGENT_CLASS_REGEX";
public static final String TRACING_ENABLED = "AGENT_TRACING_ENABLED";
public static final String SAVE_TRACED_CLASSFILES = "AGENT_SAVE_TRACED_CLASSFILES";
public static final String VERBOSE_MODE = "AGENT_VERBOSE_MODE";
public static final String ALLOW_JARS_TO_BE_TRACED = "AGENT_LLOW_JARS_TO_BE_TRACED";
}

View File

@ -0,0 +1,123 @@
package org.intrace.agent;
import org.intrace.output.IOutput;
import org.intrace.output.trace.TraceOutput;
/**
* Static implementation of the TraceWriter interface
*/
public class AgentHelper
{
private static IOutput outputHandler = new TraceOutput();
public static IOutput getActiveOutputHandler()
{
return outputHandler;
}
public static void enter(String className, String methodName)
{
outputHandler.enter(className, methodName);
}
public static void arg(String className, String methodName, byte byteArg)
{
outputHandler.arg(className, methodName, byteArg);
}
public static void arg(String className, String methodName, byte[] byteArrayArg)
{
outputHandler.arg(className, methodName, byteArrayArg);
}
public static void arg(String className, String methodName, short shortArg)
{
outputHandler.arg(className, methodName, shortArg);
}
public static void arg(String className, String methodName, short[] shortArrayArg)
{
outputHandler.arg(className, methodName, shortArrayArg);
}
public static void arg(String className, String methodName, int intArg)
{
outputHandler.arg(className, methodName, intArg);
}
public static void arg(String className, String methodName, int[] intArrayArg)
{
outputHandler.arg(className, methodName, intArrayArg);
}
public static void arg(String className, String methodName, long longArg)
{
outputHandler.arg(className, methodName, longArg);
}
public static void arg(String className, String methodName, long[] longArrayArg)
{
outputHandler.arg(className, methodName, longArrayArg);
}
public static void arg(String className, String methodName, float floatArg)
{
outputHandler.arg(className, methodName, floatArg);
}
public static void arg(String className, String methodName, float[] floatArrayArg)
{
outputHandler.arg(className, methodName, floatArrayArg);
}
public static void arg(String className, String methodName, double doubleArg)
{
outputHandler.arg(className, methodName, doubleArg);
}
public static void arg(String className, String methodName, double[] doubleArrayArg)
{
outputHandler.arg(className, methodName, doubleArrayArg);
}
public static void arg(String className, String methodName, boolean boolArg)
{
outputHandler.arg(className, methodName, boolArg);
}
public static void arg(String className, String methodName, boolean[] boolArrayArg)
{
outputHandler.arg(className, methodName, boolArrayArg);
}
public static void arg(String className, String methodName, char charArg)
{
outputHandler.arg(className, methodName, charArg);
}
public static void arg(String className, String methodName, char[] charArrayArg)
{
outputHandler.arg(className, methodName, charArrayArg);
}
public static void arg(String className, String methodName, Object objArg)
{
outputHandler.arg(className, methodName, objArg);
}
public static void arg(String className, String methodName, Object[] objArrayArg)
{
outputHandler.arg(className, methodName, objArrayArg);
}
public static void branch(String className, String methodName, int lineNo)
{
outputHandler.branch(className, methodName, lineNo);
}
public static void exit(String className, String methodName, int lineNo)
{
outputHandler.exit(className, methodName, lineNo);
}
}

View File

@ -0,0 +1,132 @@
package org.intrace.agent;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
/**
* Args Format:
* "[arg1[arg2[arg3"
*
* where argx is of the form
* value-parameter
*/
public class AgentSettings
{
private Pattern classRegex = Pattern.compile("");
private boolean tracingEnabled = false;
private boolean saveTracedClassfiles = false;
private boolean verboseMode = false;
private boolean allowJarsToBeTraced = false;
public AgentSettings(String args)
{
parseArg(args);
}
public AgentSettings(AgentSettings oldInstance)
{
classRegex = oldInstance.getClassRegex();
tracingEnabled = oldInstance.isTracingEnabled();
saveTracedClassfiles = oldInstance.saveTracedClassfiles();
verboseMode = oldInstance.isVerboseMode();
allowJarsToBeTraced = oldInstance.allowJarsToBeTraced();
}
public void parseArgs(String args)
{
String[] seperateArgs = args.split("\\[");
for (int ii = 0; ii < seperateArgs.length; ii++)
{
parseArg(seperateArgs[ii].toLowerCase());
}
}
private void parseArg(String arg)
{
if (arg.equals("verbose-true"))
{
verboseMode = true;
}
else if (arg.equals("verbose-false"))
{
verboseMode = false;
}
else if (arg.equals("instru-true"))
{
tracingEnabled = true;
}
else if (arg.equals("instru-false"))
{
tracingEnabled = false;
}
else if (arg.equals("saveinstru-true"))
{
saveTracedClassfiles = true;
}
else if (arg.equals("saveinstru-false"))
{
saveTracedClassfiles = false;
}
else if (arg.equals("instrujars-true"))
{
allowJarsToBeTraced = true;
}
else if (arg.equals("instrujars-false"))
{
allowJarsToBeTraced = false;
}
else if (arg.startsWith("regex-"))
{
String classRegexStr = arg.replace("regex-", "");
classRegex = Pattern.compile(classRegexStr);
}
}
public Pattern getClassRegex()
{
return classRegex;
}
public boolean isTracingEnabled()
{
return tracingEnabled;
}
public boolean saveTracedClassfiles()
{
return saveTracedClassfiles;
}
public boolean isVerboseMode()
{
return verboseMode;
}
public boolean allowJarsToBeTraced()
{
return allowJarsToBeTraced;
}
@Override
public String toString()
{
String currentSettings = "";
currentSettings += "Class Regex : " + classRegex + "\n";
currentSettings += "Tracing Enabled : " + tracingEnabled + "\n";
currentSettings += "Save Traced Class Files : " + saveTracedClassfiles + "\n";
currentSettings += "Trace Classes in JAR Files : " + allowJarsToBeTraced + "\n";
return currentSettings;
}
public Map<String,String> getSettingsMap()
{
Map<String,String> settingsMap = new HashMap<String, String>();
settingsMap.put(AgentConfigConstants.TRACING_ENABLED, Boolean.toString(tracingEnabled));
settingsMap.put(AgentConfigConstants.CLASS_REGEX, classRegex.pattern());
settingsMap.put(AgentConfigConstants.ALLOW_JARS_TO_BE_TRACED, Boolean.toString(allowJarsToBeTraced));
settingsMap.put(AgentConfigConstants.VERBOSE_MODE, Boolean.toString(verboseMode));
settingsMap.put(AgentConfigConstants.SAVE_TRACED_CLASSFILES, Boolean.toString(saveTracedClassfiles));
return settingsMap;
}
}

View File

@ -0,0 +1,79 @@
package org.intrace.agent;
import static org.objectweb.asm.Opcodes.GOTO;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.commons.EmptyVisitor;
/**
* First pass analysis phase
*/
public class ClassBranchLineAnalysis extends EmptyVisitor
{
private Map<String, Set<Integer>> methodBranchTraceLines = new HashMap<String, Set<Integer>>();
private Set<Integer> branchTraceLines = new HashSet<Integer>();
private Map<Label,Integer> methodLabelLineNos = new HashMap<Label,Integer>();
private String methodSig;
private boolean traceThisLine = false;
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
{
methodLabelLineNos.clear();
methodSig = name + desc;
return this;
}
@Override
public void visitLineNumber(int xiLineNo, Label xiLabel)
{
methodLabelLineNos.put(xiLabel, xiLineNo);
if (traceThisLine)
{
branchTraceLines.add(xiLineNo);
traceThisLine = false;
}
}
@Override
public void visitJumpInsn(int xiOpCode, Label xiBranchLabel)
{
if (xiOpCode != GOTO)
{
traceThisLine= true;
}
else
{
Integer lineNo = methodLabelLineNos.get(xiBranchLabel);
if (lineNo != null)
{
branchTraceLines.add(lineNo);
}
}
}
@Override
public void visitEnd()
{
if (methodSig != null)
{
methodBranchTraceLines.put(methodSig, branchTraceLines);
methodSig = null;
branchTraceLines = new HashSet<Integer>();
}
}
/**
* @return Analysis data.
*/
public Map<String, Set<Integer>> getMethodBranchLabels()
{
return methodBranchTraceLines;
}
}

View File

@ -0,0 +1,309 @@
package org.intrace.agent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;
import org.objectweb.asm.ClassReader;
/**
* Uses ASM2 to transform class files to add Trace output.
*/
public class ClassTransformer implements ClassFileTransformer
{
/**
* Map of modified class names to their original bytes
*/
private final Set<String> modifiedClasses =
new ConcurrentSkipListSet<String>();
private final Instrumentation inst;
private final AgentSettings args;
/**
* cTor
* @param xiInst
* @param xiEnableTracing
* @param xiClassRegex
* @param xiWriteModifiedClassfiles
* @param xiVerboseMode
* @param xiEnableTraceJars
*/
public ClassTransformer(Instrumentation xiInst, AgentSettings xiArgs)
{
inst = xiInst;
args = xiArgs;
if (args.isVerboseMode())
{
System.out.println(args.toString());
}
}
/**
* Toggle whether tracing is enabled
* @param xiTracingEnabled
*/
public void setTracingEnabled(boolean xiOldTracingEnabled)
{
if (args.isTracingEnabled() && !xiOldTracingEnabled)
{
traceLoadedClasses();
}
else if (!args.isTracingEnabled() && xiOldTracingEnabled)
{
recheckModifiedClasses();
}
}
/**
* Apply Trace transformation to loaded classes.
* @param xiInst
*/
public void traceLoadedClasses()
{
Class<?>[] loadedClasses = inst.getAllLoadedClasses();
for (Class<?> loadedClass : loadedClasses)
{
if (loadedClass.isAnnotation())
{
if (args.isVerboseMode())
{
System.out.println("Ignoring annotation class: " + loadedClass.getCanonicalName());
}
}
else if (loadedClass.isSynthetic())
{
if (args.isVerboseMode())
{
System.out.println("Ignoring synthetic class: " + loadedClass.getCanonicalName());
}
}
else if (!inst.isModifiableClass(loadedClass))
{
if (args.isVerboseMode())
{
System.out.println("Ignoring unmodifiable class: " + loadedClass.getCanonicalName());
}
}
else if (args.isTracingEnabled() &&
isToBeConsideredForCoverage(loadedClass.getName(), loadedClass.getProtectionDomain()))
{
try
{
inst.retransformClasses(loadedClass);
}
catch (UnmodifiableClassException e)
{
// Write exception to stdout
e.printStackTrace();
}
}
}
}
/**
* Restore original class bytes
* @param xiInst
*/
private void recheckModifiedClasses()
{
Class<?>[] loadedClasses = inst.getAllLoadedClasses();
for (Class<?> loadedClass : loadedClasses)
{
try
{
if (modifiedClasses.contains(loadedClass.getName()))
{
inst.retransformClasses(loadedClass);
}
}
catch (UnmodifiableClassException e)
{
// Write exception to stdout
e.printStackTrace();
}
}
}
private boolean isToBeConsideredForCoverage(String className,
ProtectionDomain protectionDomain)
{
// Don't modify self
if (className.startsWith("gb.instrument"))
{
if (args.isVerboseMode())
{
System.out.println("Ignoring class in gb.instrument package: " + className);
}
return false;
}
// Don't modify a class which is already modified
if (modifiedClasses.contains(className))
{
if (args.isVerboseMode())
{
System.out.println("Ignoring class already modified: " + className);
}
return false;
}
// Don't modify test classes
int p = className.lastIndexOf('$');
if (className.endsWith("Test") || p > 0
&& className.substring(0, p).endsWith("Test"))
{
if (args.isVerboseMode())
{
System.out.println("Ignoring class name ending in Test: " + className);
}
return false;
}
// Don't modify classes which fail to match the regex
if ((args.getClassRegex() == null) ||
!args.getClassRegex().matcher(className).matches())
{
if (args.isVerboseMode())
{
System.out.println("Ignoring class not matching the active regex: " + className);
}
return false;
}
// Don't modify a class from a JAR file unless this is allowed
CodeSource codeSource = protectionDomain.getCodeSource();
if (!args.allowJarsToBeTraced() &&
(codeSource != null) &&
codeSource.getLocation().getPath().endsWith(".jar"))
{
if (args.isVerboseMode())
{
System.out.println("Ignoring class in a JAR: " + className);
}
return false;
}
return true;
}
@Override
public byte[] transform(ClassLoader loader,
String internalClassName,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] originalClassfile)
throws IllegalClassFormatException
{
String className = internalClassName.replace('/', '.');
if (args.isTracingEnabled() &&
isToBeConsideredForCoverage(className, protectionDomain))
{
if (args.isVerboseMode())
{
System.out.println("!! Instrumenting class: " + className);
}
byte[] newBytes = readAndModifyClassForTracing(className, originalClassfile);
if (args.saveTracedClassfiles())
{
try
{
File classOut = new File("./genbin/" + internalClassName + "_gen.class");
File parentDir = classOut.getParentFile();
boolean dirExists = parentDir.exists();
if (!dirExists)
{
dirExists = parentDir.mkdirs();
}
if (dirExists)
{
OutputStream out = new FileOutputStream(classOut);
out.write(newBytes);
out.flush();
out.close();
}
else
{
System.out.println("Can't create directory " + parentDir +
" for saving traced classfiles.");
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
modifiedClasses.add(className);
return newBytes;
}
else
{
modifiedClasses.remove(className);
return null;
}
}
private byte[] readAndModifyClassForTracing(String xiClassName,
byte[] classfileBuffer)
{
ClassReader cr = new ClassReader(classfileBuffer);
ClassBranchLineAnalysis analysis = new ClassBranchLineAnalysis();
cr.accept(analysis, false);
InstrumentedClassWriter writer = new InstrumentedClassWriter(xiClassName,
cr,
analysis.getMethodBranchLabels());
cr.accept(writer, false);
return writer.toByteArray();
}
public String getResponse(String message)
{
AgentSettings oldSettings = new AgentSettings(args);
args.parseArgs(message);
if (args.isVerboseMode() &&
(oldSettings.isVerboseMode() != args.isVerboseMode()))
{
System.out.println(args.toString());
}
else if (oldSettings.isTracingEnabled() != args.isTracingEnabled())
{
System.out.println("## Settings Changed");
setTracingEnabled(oldSettings.isTracingEnabled());
}
else if (!oldSettings.getClassRegex().pattern().equals(args.getClassRegex().pattern()))
{
System.out.println("## Settings Changed");
recheckModifiedClasses();
traceLoadedClasses();
}
else if (oldSettings.allowJarsToBeTraced() != args.allowJarsToBeTraced())
{
System.out.println("## Settings Changed");
recheckModifiedClasses();
traceLoadedClasses();
}
else if (oldSettings.saveTracedClassfiles() != args.saveTracedClassfiles())
{
System.out.println("## Settings Changed");
recheckModifiedClasses();
traceLoadedClasses();
}
return AgentHelper.getActiveOutputHandler().getResponse(message);
}
public Map<String, String> getSettings()
{
return args.getSettingsMap();
}
}

View File

@ -0,0 +1,48 @@
package org.intrace.agent;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
/**
* ASM2 ClassWriter used to transform class files to add Trace output.
*/
public class InstrumentedClassWriter extends ClassWriter
{
private final String mClassName;
private final Map<String, Set<Integer>> methodBranchTraceLines;
/**
* cTor
*
* @param xiClassName
* @param xiReader
* @param xiMap
*/
public InstrumentedClassWriter(String xiClassName, ClassReader xiReader,
Map<String, Set<Integer>> xiMap)
{
super(xiReader, true);
mClassName = xiClassName;
methodBranchTraceLines = xiMap;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions)
{
MethodVisitor mv = super.visitMethod(access, name, desc, signature,
exceptions);
Set<Integer> branchTraceLines = methodBranchTraceLines.get(name + desc);
if (branchTraceLines == null)
{
branchTraceLines = new HashSet<Integer>();
}
return new InstrumentedMethodWriter(mv, mClassName, name, desc, branchTraceLines);
}
}

View File

@ -0,0 +1,166 @@
package org.intrace.agent;
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
import static org.objectweb.asm.Opcodes.RETURN;
import java.util.Set;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodAdapter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
/**
* ASM2 MethodVisitor used to add trace to methods.
*/
public class InstrumentedMethodWriter extends MethodAdapter
{
private static final String HELPER_CLASS = "gb/instrument/agent/AgentHelper";
private final String className;
private final String methodName;
private final String methodDescriptor;
private int lineNumber = -1;
private final Set<Integer> branchTraceLines;
private boolean writeTraceLine = false;
/**
* cTor
* @param xiMethodVisitor
* @param xiClassName
* @param xiMethodName
* @param xiDesc
* @param xiBranchTraceLines
*/
public InstrumentedMethodWriter(MethodVisitor xiMethodVisitor,
String xiClassName,
String xiMethodName,
String xiDesc,
Set<Integer> xiBranchTraceLines)
{
super(xiMethodVisitor);
className = xiClassName;
methodName = xiMethodName;
methodDescriptor = xiDesc;
branchTraceLines = xiBranchTraceLines;
}
@Override
public void visitCode()
{
generateCallToWriteBranchTrace(TraceType.BEGIN,-1);
traceArgs();
super.visitCode();
}
private void traceArgs()
{
Type[] argTypes = Type.getArgumentTypes(methodDescriptor);
for (int ii = 0; ii < argTypes.length; ii++)
{
String typeDescriptor = argTypes[ii].getDescriptor();
if (argTypes[ii].getSort() == Type.OBJECT)
{
typeDescriptor = "Ljava/lang/Object;";
}
else if ((argTypes[ii].getSort() == Type.ARRAY) &&
(argTypes[ii].getDescriptor().startsWith("[L")))
{
typeDescriptor = "[Ljava/lang/Object;";
}
mv.visitLdcInsn(className);
mv.visitLdcInsn(methodName);
mv.visitVarInsn(Opcodes.ALOAD, ii);
mv.visitMethodInsn(INVOKESTATIC,
HELPER_CLASS,
"arg",
"(Ljava/lang/String;Ljava/lang/String;" + typeDescriptor + ")V");
}
}
@Override
public void visitLineNumber(int xiLineNumber, Label label)
{
lineNumber = xiLineNumber;
if (writeTraceLine ||
branchTraceLines.contains(xiLineNumber))
{
generateCallToWriteBranchTrace(TraceType.BRANCH, lineNumber);
if (writeTraceLine)
{
writeTraceLine = false;
}
}
super.visitLineNumber(xiLineNumber, label);
}
@Override
public void visitInsn(int xiOpCode)
{
if (xiOpCode == RETURN)
{
generateCallToWriteBranchTrace(TraceType.END, lineNumber);
}
super.visitInsn(xiOpCode);
}
@Override
public void visitJumpInsn(int xiOpCode, Label xiBranchLabel)
{
writeTraceLine = true;
super.visitJumpInsn(xiOpCode, xiBranchLabel);
}
private void generateCallToWriteBranchTrace(TraceType traceType,
int lineNumber)
{
switch (traceType)
{
case BEGIN:
{
mv.visitLdcInsn(className);
mv.visitLdcInsn(methodName);
mv.visitMethodInsn(INVOKESTATIC,
HELPER_CLASS,
"enter",
"(Ljava/lang/String;Ljava/lang/String;)V");
}
break;
case BRANCH:
{
mv.visitLdcInsn(className);
mv.visitLdcInsn(methodName);
mv.visitIntInsn(Opcodes.BIPUSH, lineNumber);
mv.visitMethodInsn(INVOKESTATIC,
HELPER_CLASS,
"branch",
"(Ljava/lang/String;Ljava/lang/String;I)V");
}
break;
case END:
{
mv.visitLdcInsn(className);
mv.visitLdcInsn(methodName);
mv.visitIntInsn(Opcodes.BIPUSH, lineNumber);
mv.visitMethodInsn(INVOKESTATIC,
HELPER_CLASS,
"exit",
"(Ljava/lang/String;Ljava/lang/String;I)V");
}
break;
}
}
private enum TraceType
{
BEGIN,
BRANCH,
END
}
}

View File

@ -0,0 +1,70 @@
package org.intrace.agent.server;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import org.intrace.agent.ClassTransformer;
/**
* TCP Server used for communication with the Trace client.
*/
public class AgentServer implements Runnable
{
private final ClassTransformer transformer;
/**
* cTor
* @param xiT
*/
public AgentServer(ClassTransformer xiT)
{
transformer= xiT;
}
@Override
public void run()
{
int clientNum = 1;
int numAllowedExcept = 10;
int tracePort = 9123;
while (numAllowedExcept > 0)
{
try
{
ServerSocket serversock = new ServerSocket(tracePort);
System.out.println("Listening on port " + serversock.getLocalPort());
while (true)
{
Socket connectedClient = serversock.accept();
Thread clientThread = new Thread(new AgentServerConnection(connectedClient, transformer));
clientThread.setDaemon(true);
clientThread.setName("AgentServer-Client" + clientNum);
clientThread.start();
clientNum++;
}
}
catch (BindException e)
{
numAllowedExcept--;
System.out.println("Unable to listen on port: " + tracePort);
tracePort++;
}
catch (Throwable t)
{
numAllowedExcept--;
t.printStackTrace();
try
{
Thread.sleep(5 * 1000);
}
catch (InterruptedException e)
{
// Throw away
}
}
}
System.out.println("Too many exceptions - server thread quitting.");
}
}

View File

@ -0,0 +1,105 @@
package org.intrace.agent.server;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import org.intrace.agent.AgentHelper;
import org.intrace.agent.ClassTransformer;
/**
* Server thread handling a single connected client.
*/
public class AgentServerConnection implements Runnable
{
private final Socket connectedClient;
private final ClassTransformer transformer;
/**
* cTor
* @param xiConnectedClient
* @param xiTransformer
*/
public AgentServerConnection(Socket xiConnectedClient,
ClassTransformer xiTransformer)
{
super();
connectedClient = xiConnectedClient;
transformer = xiTransformer;
System.out.println("Connected to: " + xiConnectedClient.getPort());
}
@Override
public void run()
{
try
{
boolean quit = false;
while (!quit)
{
try
{
String message = receiveMessage(connectedClient);
if (message.equals("getsettings"))
{
Map<String,String> settingsMap = new HashMap<String, String>();
settingsMap.putAll(transformer.getSettings());
settingsMap.putAll(AgentHelper.getActiveOutputHandler().getSettingsMap());
sendMessage(connectedClient, settingsMap);
}
else
{
String response = transformer.getResponse(message);
if (response != null)
{
sendMessage(connectedClient, response);
}
else
{
sendMessage(connectedClient, "OK");
}
}
}
catch (IOException e)
{
quit = true;
}
}
System.out.println("Disconnected from: " + connectedClient.getPort());
connectedClient.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
private static String receiveMessage(Socket xiConnectedClient) throws IOException
{
InputStream in = xiConnectedClient.getInputStream();
ObjectInputStream objIn = new ObjectInputStream(in);
try
{
return (String)objIn.readObject();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
return null;
}
private static void sendMessage(Socket xiConnectedClient, Object xiObject) throws IOException
{
OutputStream out = xiConnectedClient.getOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(out);
objOut.writeObject(xiObject);
objOut.flush();
}
}

View File

@ -0,0 +1,101 @@
package org.intrace.client.cui;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.List;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
/**
* Command line agent loader.
*/
public class AgentLoader
{
/**
* Cmd line tool.
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception
{
BufferedReader readIn = new BufferedReader(new InputStreamReader(System.in));
String inLine = "";
while (!"quit".equals(inLine))
{
System.out.print("Enter command [attach/quit]: ");
inLine = readIn.readLine();
if ("attach".equals(inLine))
{
attachToVM(readIn);
}
}
}
private static void attachToVM(BufferedReader xiReadIn)
{
try
{
listProcIDs();
System.out.print("Choose VM: ");
String inLine = xiReadIn.readLine();
if (!"".equals(inLine))
{
VirtualMachine vm = VirtualMachine.attach(inLine);
System.out.println("Attached to: " + vm.id());
while (!"done".equals(inLine))
{
System.out.print("Enter command [load/done]: ");
inLine = xiReadIn.readLine();
if ("load".equals(inLine))
{
loadAgent(xiReadIn, vm);
}
}
vm.detach();
System.out.println("Detatched from: " + vm.id());
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
private static void loadAgent(BufferedReader xiReadIn, VirtualMachine vm) throws Exception
{
System.out.print("Enter path to agent jar (blank for windows default): ");
String agentPath = xiReadIn.readLine();
String defaultAgentPath = "../TestProject/lib/traceagent.jar";
if ("".equals(agentPath))
{
agentPath = defaultAgentPath;
}
System.out.println("Agent Options");
System.out.println("Leave blank for default: [regex-dcl.*");
System.out.println("After loading you can only enabled/disable trace");
System.out.print("Enter agent options: ");
String agentOptions = xiReadIn.readLine();
String defaultAgentOpt = "[regex-dcl.*";
if ("".equals(agentOptions))
{
agentOptions = defaultAgentOpt;
}
vm.loadAgent(agentPath, agentOptions);
System.out.println("Loaded agent into: " + vm.toString());
}
private static void listProcIDs()
{
System.out.println("============== Begin List ==============");
List<VirtualMachineDescriptor> vmList = VirtualMachine.list();
for (VirtualMachineDescriptor vm : vmList)
{
System.out.println(vm.displayName() + ":" + vm.id());
}
System.out.println("============== End List ==============");
}
}

View File

@ -0,0 +1,87 @@
package org.intrace.client.cui;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
/**
* Command line agent client.
*/
public class TraceClient
{
/**
* Cmd line tool.
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception
{
BufferedReader readIn = new BufferedReader(new InputStreamReader(System.in));
String inLine = "";
while (!"quit".equals(inLine))
{
System.out.print("Enter command [connect/quit]: ");
inLine = readIn.readLine();
if ("connect".equals(inLine))
{
connectToAgent(readIn);
}
}
}
private static void connectToAgent(BufferedReader xiReadIn) throws Exception
{
System.out.print("Enter host address: ");
String host = xiReadIn.readLine();
System.out.print("Enter port: ");
String port = xiReadIn.readLine();
Socket socket = new Socket();
socket.connect(new InetSocketAddress(host, Integer.valueOf(port)));
System.out.println("Connected!");
System.out.println("=> " + receiveMessage(socket));
String inLine = "";
while (!"disconnect".equals(inLine))
{
System.out.print("Enter command [help]: ");
inLine = xiReadIn.readLine();
if (!"".equals(inLine))
{
sendMessage(socket, inLine);
System.out.println("=> " + receiveMessage(socket));
}
}
}
private static String receiveMessage(Socket xiConnectedClient) throws IOException
{
InputStream in = xiConnectedClient.getInputStream();
ObjectInputStream objIn = new ObjectInputStream(in);
try
{
return (String)objIn.readObject();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
return null;
}
private static void sendMessage(Socket xiConnectedClient, String xiString) throws IOException
{
OutputStream out = xiConnectedClient.getOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(out);
objOut.writeObject(xiString);
objOut.flush();
}
}

View File

@ -0,0 +1,188 @@
package org.intrace.client.gui;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class ConnectionDetails
{
private final ExecutorService asyncExecutor = Executors.newSingleThreadExecutor(); // @jve:decl-index=0:
private Shell sShell = null; // @jve:decl-index=0:visual-constraint="10,10"
private Text addressText = null;
private Text portText = null;
private Label addressLabel = null;
private Label portLabel = null;
private Button connectButton = null;
private Label statusLabel = null;
private ConnectionDetails instanceRef = this; // @jve:decl-index=0:
public void open()
{
createSShell();
sShell.open();
Display display = Display.getDefault();
while (!sShell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
public void show()
{
sShell.setVisible(true);
sShell.setFocus();
}
public void hide()
{
sShell.setVisible(false);
}
/**
* This method initializes sShell
*/
private void createSShell()
{
GridData gridData11 = new GridData();
gridData11.horizontalAlignment = org.eclipse.swt.layout.GridData.CENTER;
gridData11.widthHint = 400;
GridData gridData2 = new GridData();
gridData2.widthHint = 400;
GridData gridData1 = new GridData();
gridData1.widthHint = 400;
GridData gridData = new GridData();
gridData.grabExcessHorizontalSpace = true;
gridData.widthHint = 200;
gridData.horizontalAlignment = org.eclipse.swt.layout.GridData.CENTER;
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 2;
sShell = new Shell(SWT.CLOSE | SWT.TITLE | SWT.MIN);
sShell.setText("Trace Client");
sShell.setLayout(gridLayout);
sShell.setSize(new Point(475, 126));
sShell.addShellListener(new org.eclipse.swt.events.ShellAdapter()
{
public void shellClosed(org.eclipse.swt.events.ShellEvent e)
{
asyncExecutor.shutdownNow();
sShell.dispose();
}
});
addressLabel = new Label(sShell, SWT.NONE);
addressLabel.setText("Address:");
addressText = new Text(sShell, SWT.BORDER);
addressText.setText("localhost");
addressText.setLayoutData(gridData1);
portLabel = new Label(sShell, SWT.NONE);
portLabel.setText("Port:");
portText = new Text(sShell, SWT.BORDER);
portText.setText("9123");
portText.setLayoutData(gridData2);
@SuppressWarnings("unused")
Label filler = new Label(sShell, SWT.NONE);
connectButton = new Button(sShell, SWT.NONE);
connectButton.setText("Connect");
connectButton.setLayoutData(gridData);
Label filler1 = new Label(sShell, SWT.NONE);
filler1.setText("Status:");
statusLabel = new Label(sShell, SWT.WRAP | SWT.LEFT);
statusLabel.setText("Enter Details Above");
statusLabel.setLayoutData(gridData11);
connectButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
{
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
{
String host = addressText.getText();
String port = portText.getText();
connectToAgent(host, port);
}
});
}
private void connectToAgent(final String host, final String port)
{
if (host.length() == 0)
{
sShell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
statusLabel.setText("Please enter an address");
}
});
}
else if (port.length() == 0)
{
sShell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
statusLabel.setText("Please enter a port");
}
});
}
else
{
sShell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
statusLabel.setText("Connecting...");
asyncExecutor.execute(new Runnable()
{
@Override
public void run()
{
final Socket socket = new Socket();
String statusMessage;
try
{
socket.connect(new InetSocketAddress(host, Integer.valueOf(port)));
statusMessage = "Connected";
sShell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
hide();
TraceWindow traceWindow = new TraceWindow(instanceRef, socket);
traceWindow.open();
}
});
}
catch (Exception e)
{
statusMessage = e.toString();
}
final String statusMessageRef = statusMessage;
sShell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
statusLabel.setText(statusMessageRef);
}
});
}
});
}
});
}
}
}

View File

@ -0,0 +1,108 @@
package org.intrace.client.gui;
import java.util.Map;
import org.intrace.agent.AgentConfigConstants;
import org.intrace.output.trace.TraceConfigConstants;
public class ParsedSettingsData
{
public final String classRegex;
public final boolean instrEnabled;
public final boolean saveTracedClassfiles;
public final boolean verboseMode;
public final boolean allowJarsToBeTraced;
public final boolean entryExitEnabled;
public final boolean branchEnabled;
public final boolean argsEnabled;
public final boolean stdOutEnabled;
public final boolean fileOutEnabled;
public ParsedSettingsData(Map<String, String> settingsMap)
{
classRegex = settingsMap.get(AgentConfigConstants.CLASS_REGEX);
if ("true".equals(settingsMap.get(AgentConfigConstants.TRACING_ENABLED)))
{
instrEnabled = true;
}
else
{
instrEnabled = false;
}
if ("true".equals(settingsMap.get(AgentConfigConstants.SAVE_TRACED_CLASSFILES)))
{
saveTracedClassfiles = true;
}
else
{
saveTracedClassfiles = false;
}
if ("true".equals(settingsMap.get(AgentConfigConstants.VERBOSE_MODE)))
{
verboseMode = true;
}
else
{
verboseMode = false;
}
if ("true".equals(settingsMap.get(AgentConfigConstants.ALLOW_JARS_TO_BE_TRACED)))
{
allowJarsToBeTraced = true;
}
else
{
allowJarsToBeTraced = false;
}
if ("true".equals(settingsMap.get(TraceConfigConstants.ENTRY_EXIT)))
{
entryExitEnabled = true;
}
else
{
entryExitEnabled = false;
}
if ("true".equals(settingsMap.get(TraceConfigConstants.BRANCH)))
{
branchEnabled = true;
}
else
{
branchEnabled = false;
}
if ("true".equals(settingsMap.get(TraceConfigConstants.ARG)))
{
argsEnabled = true;
}
else
{
argsEnabled = false;
}
if ("true".equals(settingsMap.get(TraceConfigConstants.STD_OUT)))
{
stdOutEnabled = true;
}
else
{
stdOutEnabled = false;
}
if ("true".equals(settingsMap.get(TraceConfigConstants.FILE_OUT)))
{
fileOutEnabled = true;
}
else
{
fileOutEnabled = false;
}
}
}

View File

@ -0,0 +1,81 @@
package org.intrace.client.gui;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class RegexInput
{
private Shell sShell = null; // @jve:decl-index=0:visual-constraint="10,10"
private Text regexInput = null;
private Button setRegexButton = null;
private Button cancelButton = null;
private TraceWindow instanceRef = null; // @jve:decl-index=0:
/**
* This method initializes sShell
*/
private void createSShell()
{
GridData gridData2 = new GridData();
gridData2.widthHint = 100;
gridData2.horizontalAlignment = org.eclipse.swt.layout.GridData.CENTER;
GridData gridData1 = new GridData();
gridData1.widthHint = 100;
gridData1.horizontalAlignment = org.eclipse.swt.layout.GridData.CENTER;
GridData gridData = new GridData();
gridData.horizontalSpan = 2;
gridData.widthHint = 300;
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 2;
gridLayout.makeColumnsEqualWidth = true;
sShell = new Shell(SWT.APPLICATION_MODAL | SWT.CLOSE | SWT.TITLE | SWT.MIN);
sShell.setText("Enter Regex");
sShell.setLayout(gridLayout);
sShell.setSize(new Point(326, 82));
sShell.addShellListener(new org.eclipse.swt.events.ShellAdapter()
{
public void shellClosed(org.eclipse.swt.events.ShellEvent e)
{
sShell.dispose();
}
});
regexInput = new Text(sShell, SWT.BORDER);
regexInput.setLayoutData(gridData);
setRegexButton = new Button(sShell, SWT.NONE);
setRegexButton.setText("Set Class Regex");
setRegexButton.setLayoutData(gridData1);
setRegexButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
{
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
{
instanceRef.setRegex(regexInput.getText());
sShell.close();
}
});
cancelButton = new Button(sShell, SWT.NONE);
cancelButton.setText("Cancel");
cancelButton.setLayoutData(gridData2);
cancelButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
{
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
{
sShell.close();
}
});
}
public void open(TraceWindow instanceWindowRef, String initText)
{
createSShell();
sShell.open();
regexInput.setText(initText);
instanceRef = instanceWindowRef;
}
}

View File

@ -0,0 +1,14 @@
package org.intrace.client.gui;
public class TraceClient
{
/**
* @param args
*/
public static void main(String[] args)
{
ConnectionDetails enterConnectionDetails = new ConnectionDetails();
enterConnectionDetails.open();
}
}

View File

@ -0,0 +1,617 @@
package org.intrace.client.gui;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.layout.FillLayout;
public class TraceWindow
{
private final String ENABLE_INSTR = "Enable Instrumentation";
private final String DISABLE_INSTR = "Disable Instrumentation";
private final String SET_CLASSREGEX = "Set Class Regex...";
private final String ENABLE_ALLOWJARS = "Enable JAR Instrumentation";
private final String DISABLE_ALLOWJARS = "Disable JAR Instrumentation";
private final String ENABLE_SAVECLASSES = "Save Instrumented Classes";
private final String DISABLE_SAVECLASSES = "Don't Save Classes";
private final String ENABLE_VERBOSEMODE = "Enable Verbose Mode";
private final String DISABLE_VERBOSEMODE = "Disable Verbose Mode";
private final String ENABLE_EE_TRACE = "Enable Entry/Exit Trace";
private final String DISABLE_EE_TRACE = "Disable Entry/Exit Trace";
private final String ENABLE_BRANCH_TRACE = "Enable Branch Trace";
private final String DISABLE_BRANCH_TRACE = "Disable Branch Trace";
private final String ENABLE_ARGS_TRACE = "Enable Args Trace";
private final String DISABLE_ARGS_TRACE = "Disable Args Trace";
private final String ENABLE_STDOUT_TRACE = "Enable StdOut Trace";
private final String DISABLE_STDOUT_TRACE = "Disable StdOut Trace";
private final String ENABLE_FILE_TRACE = "Enable File Trace";
private final String DISABLE_FILE_TRACE = "Disable File Trace";
private final String ENABLE_NETWORK_TRACE = "Enable Network Trace";
private final String DISABLE_NETWORK_TRACE = "Disable Network Trace";
private ParsedSettingsData settingsData = new ParsedSettingsData(new HashMap<String, String>()); // @jve:decl-index=0:
private final ExecutorService asyncExecutor = Executors.newSingleThreadExecutor(); // @jve:decl-index=0:
private TraceWindow instanceWindowRef = this;
private boolean networkTraceEnabled = false;
private NetworkTraceThread networkThread;
private Shell sShell = null;
private Button toggleEntryExitButton = null;
private Button Disconnect = null;
private Text statusTextArea = null;
private ConnectionDetails instanceRef;
private Socket socket;
private Button toggleStdOutButton = null;
private Button toggleBranchButton = null;
private Button toggleArgsButton = null;
private Label traceSettingsLabel = null;
private Label outputSettingsLabel = null;
private Label spacerLabel = null;
private Composite composite = null;
private Label instrumentSettingsLabel = null;
private Button toggleInstrumentEnabled = null;
private Button setClassRegexButton = null;
private Button toggleAllowJarInstru = null;
private Button toggleSaveClassFiles = null;
private Button toggleVerboseMode = null;
private Button toggleFileOutputButton = null;
private Button toggleNetworkTraceButton = null;
public TraceWindow(ConnectionDetails instanceRef, Socket socket)
{
this.instanceRef = instanceRef;
this.socket = socket;
}
/**
* This method initializes sShell
*/
private void createSShell()
{
GridData gridData22 = new GridData();
gridData22.widthHint = 150;
GridData gridData11 = new GridData();
gridData11.widthHint = 150;
GridData gridData7 = new GridData();
gridData7.widthHint = 150;
GridData gridData6 = new GridData();
gridData6.widthHint = 150;
GridData gridData5 = new GridData();
gridData5.widthHint = 150;
GridData gridData41 = new GridData();
gridData41.widthHint = 150;
GridData gridData31 = new GridData();
gridData31.widthHint = 150;
GridData gridData21 = new GridData();
gridData21.widthHint = 150;
GridData gridData1 = new GridData();
gridData1.widthHint = 150;
GridData gridData4 = new GridData();
gridData4.widthHint = 150;
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 2;
GridData gridData2 = new GridData();
gridData2.widthHint = 150;
GridData gridData = new GridData();
gridData.widthHint = 150;
gridData.verticalAlignment = org.eclipse.swt.layout.GridData.BEGINNING;
sShell = new Shell();
sShell.setText("Trace Window");
sShell.setLayout(gridLayout);
sShell.setSize(new Point(500, 500));
instrumentSettingsLabel = new Label(sShell, SWT.NONE);
instrumentSettingsLabel.setText("Instrumentation Settings:");
createComposite();
toggleInstrumentEnabled = new Button(sShell, SWT.LEFT);
toggleInstrumentEnabled.setText(ENABLE_INSTR);
toggleInstrumentEnabled.setLayoutData(gridData31);
toggleInstrumentEnabled
.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
{
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
{
toggleSetting(settingsData.instrEnabled, "[instru-true", "[instru-false");
}
});
setClassRegexButton = new Button(sShell, SWT.LEFT);
setClassRegexButton.setText(SET_CLASSREGEX);
setClassRegexButton.setLayoutData(gridData41);
setClassRegexButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
{
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
{
RegexInput regexInput = new RegexInput();
regexInput.open(instanceWindowRef, settingsData.classRegex);
}
});
toggleAllowJarInstru = new Button(sShell, SWT.LEFT);
toggleAllowJarInstru.setText(ENABLE_ALLOWJARS);
toggleAllowJarInstru.setLayoutData(gridData5);
toggleAllowJarInstru.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
{
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
{
toggleSetting(settingsData.allowJarsToBeTraced, "[instrujars-true", "[instrujars-false");
}
});
toggleSaveClassFiles = new Button(sShell, SWT.LEFT);
toggleSaveClassFiles.setText(ENABLE_SAVECLASSES);
toggleSaveClassFiles.setLayoutData(gridData6);
toggleSaveClassFiles.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
{
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
{
toggleSetting(settingsData.saveTracedClassfiles, "[saveinstru-true", "[saveinstru-false");
}
});
toggleVerboseMode = new Button(sShell, SWT.LEFT);
toggleVerboseMode.setText(ENABLE_VERBOSEMODE);
toggleVerboseMode.setLayoutData(gridData7);
toggleVerboseMode.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
{
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
{
toggleSetting(settingsData.verboseMode, "[verbose-true", "[verbose-false");
}
});
sShell.setMinimumSize(new Point(500, 500));
traceSettingsLabel = new Label(sShell, SWT.NONE);
traceSettingsLabel.setText("Trace Settings:");
sShell.addShellListener(new org.eclipse.swt.events.ShellAdapter()
{
public void shellClosed(org.eclipse.swt.events.ShellEvent e)
{
disconnect();
sShell.dispose();
asyncExecutor.shutdownNow();
}
});
toggleEntryExitButton = new Button(sShell, SWT.LEFT);
toggleEntryExitButton.setText(ENABLE_EE_TRACE);
toggleEntryExitButton.setLayoutData(gridData2);
toggleEntryExitButton
.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
{
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
{
toggleSetting(settingsData.entryExitEnabled, "[trace-ee-true", "[trace-ee-false");
}
});
toggleBranchButton = new Button(sShell, SWT.LEFT);
toggleBranchButton.setText(ENABLE_BRANCH_TRACE);
toggleBranchButton.setLayoutData(gridData1);
toggleBranchButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
{
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
{
toggleSetting(settingsData.branchEnabled, "[trace-branch-true", "[trace-branch-false");
}
});
toggleArgsButton = new Button(sShell, SWT.LEFT);
toggleArgsButton.setText(ENABLE_ARGS_TRACE);
toggleArgsButton.setLayoutData(gridData21);
outputSettingsLabel = new Label(sShell, SWT.NONE);
outputSettingsLabel.setText("Output Modes:");
toggleArgsButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
{
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
{
toggleSetting(settingsData.argsEnabled, "[trace-args-true", "[trace-args-false");
}
});
toggleStdOutButton = new Button(sShell, SWT.LEFT);
toggleStdOutButton.setText(ENABLE_STDOUT_TRACE);
toggleStdOutButton.setLayoutData(gridData4);
toggleFileOutputButton = new Button(sShell, SWT.LEFT);
toggleFileOutputButton.setText(ENABLE_FILE_TRACE);
toggleFileOutputButton.setLayoutData(gridData11);
toggleNetworkTraceButton = new Button(sShell, SWT.LEFT);
toggleNetworkTraceButton.setText(ENABLE_NETWORK_TRACE);
toggleNetworkTraceButton.setLayoutData(gridData22);
toggleNetworkTraceButton
.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
{
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
{
toggleNetworkTrace();
}
});
toggleFileOutputButton
.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
{
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
{
toggleSetting(settingsData.fileOutEnabled, "[trace-file-true", "[trace-file-false");
}
});
spacerLabel = new Label(sShell, SWT.NONE);
spacerLabel.setText("");
toggleStdOutButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
{
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
{
toggleSetting(settingsData.stdOutEnabled, "[trace-stdout-true", "[trace-stdout-false");
}
});
Disconnect = new Button(sShell, SWT.LEFT);
Disconnect.setText("Disconnect");
Disconnect.setLayoutData(gridData);
Disconnect.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
{
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
{
sShell.close();
}
});
}
/**
* This method initializes composite
*
*/
private void createComposite()
{
FillLayout fillLayout = new FillLayout();
fillLayout.type = org.eclipse.swt.SWT.HORIZONTAL;
GridData gridData3 = new GridData();
gridData3.grabExcessVerticalSpace = true;
gridData3.heightHint = 99999;
gridData3.widthHint = 99999;
gridData3.verticalSpan = 17;
gridData3.grabExcessHorizontalSpace = true;
composite = new Composite(sShell, SWT.NONE);
composite.setLayoutData(gridData3);
composite.setLayout(fillLayout);
statusTextArea = new Text(composite, SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.BORDER);
statusTextArea.setEditable(false);
statusTextArea.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
}
public void open()
{
createSShell();
sShell.open();
statusTextArea.append("Connected!\n");
getSettings();
}
private void toggleNetworkTrace()
{
sShell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
disableButtons();
asyncExecutor.execute(new Runnable()
{
@Override
public void run()
{
try
{
if (!networkTraceEnabled)
{
sendMessage("[trace-network");
String networkTracePortStr = (String)receiveMessage();
int networkTracePort = Integer.parseInt(networkTracePortStr);
networkThread = new NetworkTraceThread(networkTracePort);
networkThread.start();
networkTraceEnabled = true;
}
else
{
networkThread.stop();
networkTraceEnabled = false;
}
sShell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
updateButtonText();
}
});
}
catch (IOException e)
{
sShell.close();
}
}
});
}
});
}
public void setRegex(final String regex)
{
sShell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
disableButtons();
asyncExecutor.execute(new Runnable()
{
@Override
public void run()
{
try
{
sendMessage("[regex-" + regex);
receiveMessage(); // Throw away result message
sShell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
getSettings();
}
});
}
catch (IOException e)
{
sShell.close();
}
}
});
}
});
}
private void getSettings()
{
sShell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
statusTextArea.append("Fetching Settings...\n");
}
});
asyncExecutor.execute(new Runnable()
{
@SuppressWarnings("unchecked")
@Override
public void run()
{
try
{
sendMessage("getsettings");
Object receivedMsg = receiveMessage();
if (receivedMsg instanceof Map)
{
Map<String,String> settingsMap = (Map<String,String>)receivedMsg;
settingsData = new ParsedSettingsData(settingsMap);
sShell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
updateButtonText();
}
});
}
}
catch (IOException e)
{
sShell.close();
}
}
});
}
private void toggleSetting(final boolean settingValue, final String enableCommand, final String disableCommand)
{
sShell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
disableButtons();
asyncExecutor.execute(new Runnable()
{
@Override
public void run()
{
try
{
if (settingValue)
{
sendMessage(disableCommand);
}
else
{
sendMessage(enableCommand);
}
receiveMessage(); // Throw away result message
sShell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
getSettings();
}
});
}
catch (IOException e)
{
sShell.close();
}
}
});
}
});
}
private void disableButtons()
{
toggleInstrumentEnabled.setEnabled(false);
setClassRegexButton.setEnabled(false);
toggleAllowJarInstru.setEnabled(false);
toggleSaveClassFiles.setEnabled(false);
toggleVerboseMode.setEnabled(false);
toggleEntryExitButton.setEnabled(false);
toggleBranchButton.setEnabled(false);
toggleArgsButton.setEnabled(false);
toggleStdOutButton.setEnabled(false);
toggleFileOutputButton.setEnabled(false);
toggleNetworkTraceButton.setEnabled(false);
}
private void chooseText(Button control, boolean option, String enabledText, String disabledText)
{
if (option)
{
control.setText(disabledText);
}
else
{
control.setText(enabledText);
}
control.setEnabled(true);
}
private void updateButtonText()
{
statusTextArea.append("Got Settings...\n");
chooseText(toggleInstrumentEnabled, settingsData.instrEnabled, ENABLE_INSTR, DISABLE_INSTR);
chooseText(toggleAllowJarInstru, settingsData.allowJarsToBeTraced, ENABLE_ALLOWJARS, DISABLE_ALLOWJARS);
chooseText(toggleSaveClassFiles, settingsData.saveTracedClassfiles, ENABLE_SAVECLASSES, DISABLE_SAVECLASSES);
chooseText(toggleVerboseMode, settingsData.verboseMode, ENABLE_VERBOSEMODE, DISABLE_VERBOSEMODE);
chooseText(toggleEntryExitButton, settingsData.entryExitEnabled, ENABLE_EE_TRACE, DISABLE_EE_TRACE);
chooseText(toggleBranchButton, settingsData.branchEnabled, ENABLE_BRANCH_TRACE, DISABLE_BRANCH_TRACE);
chooseText(toggleArgsButton, settingsData.argsEnabled, ENABLE_ARGS_TRACE, DISABLE_ARGS_TRACE);
chooseText(toggleStdOutButton, settingsData.stdOutEnabled, ENABLE_STDOUT_TRACE, DISABLE_STDOUT_TRACE);
chooseText(toggleFileOutputButton, settingsData.fileOutEnabled, ENABLE_FILE_TRACE, DISABLE_FILE_TRACE);
chooseText(toggleNetworkTraceButton, networkTraceEnabled, ENABLE_NETWORK_TRACE, DISABLE_NETWORK_TRACE);
setClassRegexButton.setEnabled(true);
}
private void disconnect()
{
if (socket.isConnected())
{
try
{
socket.close();
}
catch (IOException e)
{
// Throw away
}
instanceRef.show();
}
}
private Object receiveMessage() throws IOException
{
InputStream in = socket.getInputStream();
ObjectInputStream objIn = new ObjectInputStream(in);
try
{
return (Object)objIn.readObject();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
return null;
}
private void sendMessage(String xiString) throws IOException
{
OutputStream out = socket.getOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(out);
objOut.writeObject(xiString);
objOut.flush();
}
private class NetworkTraceThread implements Runnable
{
private final Socket traceSocket;
public NetworkTraceThread(int networkTracePort) throws IOException
{
traceSocket = new Socket();
traceSocket.connect(new InetSocketAddress(socket.getInetAddress(), networkTracePort));
}
public void start()
{
Thread t = new Thread(this);
t.setDaemon(true);
t.setName("Network Trace");
t.start();
}
public void stop()
{
try
{
traceSocket.close();
}
catch (IOException e)
{
// Throw away
}
}
@Override
public void run()
{
try
{
ObjectInputStream objIn = new ObjectInputStream(traceSocket.getInputStream());
while (true)
{
final String traceLine = (String)objIn.readObject();
sShell.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
statusTextArea.append(traceLine + "\n");
}
});
}
}
catch (Exception e)
{
// Throw away
}
}
}
}

View File

@ -0,0 +1,40 @@
package org.intrace.output;
import java.util.Map;
/**
* Output generated by the instrumentation
*/
public interface IOutput
{
public void enter(String className, String methodName);
public void arg(String className, String methodName, byte byteArg);
public void arg(String className, String methodName, byte[] byteArrayArg);
public void arg(String className, String methodName, short shortArg);
public void arg(String className, String methodName, short[] shortArrayArg);
public void arg(String className, String methodName, int intArg);
public void arg(String className, String methodName, int[] intArrayArg);
public void arg(String className, String methodName, long longArg);
public void arg(String className, String methodName, long[] longArrayArg);
public void arg(String className, String methodName, float floatArg);
public void arg(String className, String methodName, float[] floatArrayArg);
public void arg(String className, String methodName, double doubleArg);
public void arg(String className, String methodName, double[] doubleArrayArg);
public void arg(String className, String methodName, boolean boolArg);
public void arg(String className, String methodName, boolean[] boolArrayArg);
public void arg(String className, String methodName, char charArg);
public void arg(String className, String methodName, char[] charArrayArg);
public void arg(String className, String methodName, Object objArg);
public void arg(String className, String methodName, Object[] objArrayArg);
public void branch(String className, String methodName, int lineNo);
public void exit(String className, String methodName, int lineNo);
public String getResponse(String args);
public Map<String,String> getSettingsMap();
}

View File

@ -0,0 +1,85 @@
package org.intrace.output.trace;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class NetworkTraceThread implements Runnable
{
private final ServerSocket networkSocket;
private final BlockingQueue<String> outgoingTrace = new LinkedBlockingQueue<String>(100);
private Set<NetworkTraceThread> set;
public NetworkTraceThread(ServerSocket networkSocket)
{
this.networkSocket = networkSocket;
}
public void start(Set<NetworkTraceThread> set)
{
this.set = set;
Thread networkThread = new Thread(this);
networkThread.setDaemon(true);
networkThread.setName("Network-Trace");
networkThread.start();
}
private void stop()
{
try
{
networkSocket.close();
}
catch (IOException e)
{
// Throw away
}
set.remove(this);
System.out.println("## Network Trace Disconnected");
}
public void queueTrace(String traceLine)
{
try
{
outgoingTrace.put(traceLine);
}
catch (InterruptedException e)
{
// Throw away
}
}
@Override
public void run()
{
Socket traceSendingSocket;
try
{
traceSendingSocket = networkSocket.accept();
try
{
ObjectOutputStream traceWriter = new ObjectOutputStream(traceSendingSocket.getOutputStream());
while (true)
{
String traceLine = outgoingTrace.take();
traceWriter.writeObject(traceLine);
}
}
catch (Exception e)
{
traceSendingSocket.close();
throw e;
}
}
catch (Exception e1)
{
stop();
}
}
}

View File

@ -0,0 +1,10 @@
package org.intrace.output.trace;
public class TraceConfigConstants
{
public static final String ENTRY_EXIT = "TRACE_ENTRY_EXIT";
public static final String BRANCH = "TRACE_BRANCH";
public static final String ARG = "TRACE_ARG";
public static final String STD_OUT = "TRACE_STD_OUT";
public static final String FILE_OUT = "TRACE_FILE_OUT";
}

View File

@ -0,0 +1,336 @@
package org.intrace.output.trace;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.intrace.output.IOutput;
/**
* Implements Standard Output Tracing
*/
public class TraceOutput implements IOutput
{
private boolean entryExitTrace = true;
private boolean branchTrace = false;
private boolean argTrace = false;
private boolean stdoutTrace = true;
private boolean fileoutTrace = false;
private boolean file1Active = true;
private int writtenChars = 0;
private final int MAX_CHARS_PER_FILE = 100 * 1000; // 100kb
final TraceSettings traceSettings = new TraceSettings("");
private Map<NetworkTraceThread,Object> traceThreads = new ConcurrentHashMap<NetworkTraceThread,Object>();
public String getResponse(String args)
{
TraceSettings oldSettings = new TraceSettings(traceSettings);
traceSettings.parseArgs(args);
if ((oldSettings.isEntryExitTraceEnabled() != traceSettings.isEntryExitTraceEnabled()) ||
(oldSettings.isBranchTraceEnabled() != traceSettings.isBranchTraceEnabled()) ||
(oldSettings.isArgTraceEnabled() != traceSettings.isArgTraceEnabled()) ||
(oldSettings.isStdoutTraceOutputEnabled() != traceSettings.isStdoutTraceOutputEnabled()) ||
(oldSettings.isFileTraceOutputEnabled() != traceSettings.isFileTraceOutputEnabled()))
{
System.out.println("## Trace Settings Changed");
}
entryExitTrace = traceSettings.isEntryExitTraceEnabled();
branchTrace = traceSettings.isBranchTraceEnabled();
argTrace = traceSettings.isArgTraceEnabled();
stdoutTrace = traceSettings.isStdoutTraceOutputEnabled();
fileoutTrace = traceSettings.isFileTraceOutputEnabled();
if (traceSettings.networkTraceOutputRequested)
{
System.out.println("## Network Trace Requested");
ServerSocket networkSocket;
try
{
networkSocket = new ServerSocket(0);
NetworkTraceThread traceThread = new NetworkTraceThread(networkSocket);
traceThreads.put(traceThread, new Object());
traceThread.start(traceThreads.keySet());
traceSettings.networkTraceOutputRequested = false;
return Integer.toString(networkSocket.getLocalPort());
}
catch (IOException e)
{
// Do nothing
return null;
}
}
else
{
return null;
}
}
public Map<String,String> getSettingsMap()
{
return traceSettings.getSettingsMap();
}
/**
* Write trace output
*
* @param xiTrace
*/
private void writeTrace(String xiTrace)
{
SimpleDateFormat dateFormat = new SimpleDateFormat();
long threadID = Thread.currentThread().getId();
String traceString = "[" + dateFormat.format(new Date()) + "]:[" +
threadID + "]:" + xiTrace;
if (stdoutTrace)
{
System.out.println(traceString);
}
if (fileoutTrace)
{
writeFileTrace(traceString);
}
Set<NetworkTraceThread> networkThreads = traceThreads.keySet();
if (networkThreads.size() > 0)
{
for (NetworkTraceThread thread : networkThreads)
{
thread.queueTrace(traceString);
}
}
}
private synchronized void writeFileTrace(String traceString)
{
PrintWriter outputWriter;
if (file1Active)
{
outputWriter = traceSettings.getFile1TraceWriter();
}
else
{
outputWriter = traceSettings.getFile2TraceWriter();
}
outputWriter.println(traceString);
outputWriter.flush();
// Switch trace files if necessary
writtenChars += traceString.length();
if (writtenChars > MAX_CHARS_PER_FILE)
{
writtenChars = 0;
traceSettings.resetTraceFiles(file1Active, !file1Active);
file1Active = !file1Active;
}
}
@Override
public void arg(String className, String methodName, byte byteArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: " + byteArg);
}
}
public void arg(String className, String methodName, byte[] byteArrayArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: "
+ Arrays.toString(byteArrayArg));
}
}
@Override
public void arg(String className, String methodName, short shortArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: " + shortArg);
}
}
public void arg(String className, String methodName, short[] shortArrayArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: "
+ Arrays.toString(shortArrayArg));
}
}
@Override
public void arg(String className, String methodName, int intArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: " + intArg);
}
}
@Override
public void arg(String className, String methodName, int[] intArrayArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: "
+ Arrays.toString(intArrayArg));
}
}
@Override
public void arg(String className, String methodName, long longArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: " + longArg);
}
}
@Override
public void arg(String className, String methodName, long[] longArrayArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: "
+ Arrays.toString(longArrayArg));
}
}
@Override
public void arg(String className, String methodName, float floatArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: " + floatArg);
}
}
@Override
public void arg(String className, String methodName, float[] floatArrayArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: "
+ Arrays.toString(floatArrayArg));
}
}
@Override
public void arg(String className, String methodName, double doubleArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: " + doubleArg);
}
}
@Override
public void arg(String className, String methodName, double[] doubleArrayArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: "
+ Arrays.toString(doubleArrayArg));
}
}
@Override
public void arg(String className, String methodName, boolean boolArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: " + boolArg);
}
}
@Override
public void arg(String className, String methodName, boolean[] boolArrayArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: "
+ Arrays.toString(boolArrayArg));
}
}
@Override
public void arg(String className, String methodName, char charArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: " + charArg);
}
}
@Override
public void arg(String className, String methodName, char[] charArrayArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: "
+ Arrays.toString(charArrayArg));
}
}
@Override
public void arg(String className, String methodName, Object objArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: " + objArg);
}
}
public void arg(String className, String methodName, Object[] objArrayArg)
{
if (argTrace)
{
writeTrace(className + ":" + methodName + ": Arg: "
+ Arrays.toString(objArrayArg));
}
}
@Override
public void branch(String className, String methodName, int lineNo)
{
if (branchTrace)
{
writeTrace(className + ":" + methodName + ": /:" + lineNo);
}
}
@Override
public void enter(String className, String methodName)
{
if (entryExitTrace)
{
writeTrace(className + ":" + methodName + ": {");
}
}
@Override
public void exit(String className, String methodName, int lineNo)
{
if (entryExitTrace)
{
writeTrace(className + ":" + methodName + ": }:" + lineNo);
}
}
}

View File

@ -0,0 +1,185 @@
package org.intrace.output.trace;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
/**
* Args Format:
* "[arg1[arg2[arg3"
*
* where argx is of the form
* value-parameter
*/
public class TraceSettings
{
private boolean entryExitTraceEnabled = true;
private boolean branchTraceEnabled = false;
private boolean argTraceEnabled = false;
private boolean stdoutTraceOutputEnabled = true;
private boolean fileTraceOutputEnabled = false;
private File file1;
private File file2;
private PrintWriter file1TraceWriter;
private PrintWriter file2TraceWriter;
public boolean networkTraceOutputRequested = false;
public TraceSettings(TraceSettings oldSettings)
{
entryExitTraceEnabled = oldSettings.entryExitTraceEnabled;
branchTraceEnabled = oldSettings.branchTraceEnabled;
argTraceEnabled = oldSettings.argTraceEnabled;
stdoutTraceOutputEnabled = oldSettings.stdoutTraceOutputEnabled;
fileTraceOutputEnabled = oldSettings.fileTraceOutputEnabled;
}
public TraceSettings(String args)
{
file1 = new File("trc1.txt");
file2 = new File("trc2.txt");
resetTraceFiles(true, true);
parseArgs(args);
}
public void parseArgs(String args)
{
String[] seperateArgs = args.split("\\[");
for (int ii = 0; ii < seperateArgs.length; ii++)
{
parseArg(seperateArgs[ii].toLowerCase());
}
}
private void parseArg(String arg)
{
if (arg.equals("trace-ee-false"))
{
entryExitTraceEnabled = false;
}
else if (arg.equals("trace-ee-true"))
{
entryExitTraceEnabled = true;
}
else if (arg.equals("trace-branch-true"))
{
branchTraceEnabled = true;
}
else if (arg.equals("trace-branch-false"))
{
branchTraceEnabled = false;
}
else if (arg.equals("trace-args-true"))
{
argTraceEnabled = true;
}
else if (arg.equals("trace-args-false"))
{
argTraceEnabled = false;
}
else if (arg.equals("trace-stdout-true"))
{
stdoutTraceOutputEnabled = true;
}
else if (arg.equals("trace-stdout-false"))
{
stdoutTraceOutputEnabled = false;
}
else if (arg.equals("trace-file-true"))
{
fileTraceOutputEnabled = true;
}
else if (arg.equals("trace-file-false"))
{
fileTraceOutputEnabled = false;
}
else if (arg.startsWith("trace-file1-"))
{
String file1Name = arg.replace("trace-file1-", "");
file1 = new File(file1Name);
resetTraceFiles(true, false);
}
else if (arg.startsWith("trace-file2-"))
{
String file2Name = arg.replace("trace-file2-", "");
file2 = new File(file2Name);
resetTraceFiles(false, true);
}
else if (arg.equals("trace-network"))
{
networkTraceOutputRequested = true;
}
}
public void resetTraceFiles(boolean resetFile1, boolean resetFile2)
{
try
{
if (resetFile1)
{
file1.delete();
file1TraceWriter = new PrintWriter(new FileWriter(file1));
}
if (resetFile2)
{
file2.delete();
file2TraceWriter = new PrintWriter(new FileWriter(file2));
}
}
catch (IOException e)
{
// Throw away
}
}
public boolean isEntryExitTraceEnabled()
{
return entryExitTraceEnabled;
}
public boolean isBranchTraceEnabled()
{
return branchTraceEnabled;
}
public boolean isArgTraceEnabled()
{
return argTraceEnabled;
}
public boolean isStdoutTraceOutputEnabled()
{
return stdoutTraceOutputEnabled;
}
public boolean isFileTraceOutputEnabled()
{
return fileTraceOutputEnabled;
}
public PrintWriter getFile1TraceWriter()
{
return file1TraceWriter;
}
public PrintWriter getFile2TraceWriter()
{
return file2TraceWriter;
}
public Map<String,String> getSettingsMap()
{
Map<String,String> settingsMap = new HashMap<String, String>();
settingsMap.put(TraceConfigConstants.ENTRY_EXIT, Boolean.toString(entryExitTraceEnabled));
settingsMap.put(TraceConfigConstants.BRANCH, Boolean.toString(branchTraceEnabled));
settingsMap.put(TraceConfigConstants.ARG, Boolean.toString(argTraceEnabled));
settingsMap.put(TraceConfigConstants.STD_OUT, Boolean.toString(stdoutTraceOutputEnabled));
settingsMap.put(TraceConfigConstants.FILE_OUT, Boolean.toString(fileTraceOutputEnabled));
return settingsMap;
}
}