diff --git a/org.intrace/src/org/intrace/agent/AgentInit.java b/org.intrace/src/org/intrace/agent/AgentInit.java index 3c792d1..cde945b 100644 --- a/org.intrace/src/org/intrace/agent/AgentInit.java +++ b/org.intrace/src/org/intrace/agent/AgentInit.java @@ -16,47 +16,47 @@ public class AgentInit /** * Common init function. - * + * * @param agentArgs * @param inst */ public static void initialize(String agentArgs, Instrumentation inst) { System.out.println("## Loaded InTrace Agent."); - + if (agentArgs == null) { agentArgs = ""; } - + // Setup the trace instrumentation handler AgentHelper.setInstrumentationHandler(TraceHandler.INSTANCE); - + // Parse startup args AgentSettings args = new AgentSettings(agentArgs); AgentHelper.getResponses(null, agentArgs); - + // Construct Transformer ClassTransformer t = new ClassTransformer(inst, args); - inst.addTransformer(t, true); - + inst.addTransformer(t, inst.isRetransformClassesSupported()); + // Ensure loaded classes are traced t.instrumentKlasses(t.getLoadedClassesForModification()); - + // Start Server thread new AgentServer(t, args.getServerPort()).start(); - + // Store server port waitForServerPort(); args.setActualServerPort(serverPort); - + // Wait for callback connection if (args.getCallbackPort() > -1) { System.out.println("## Establishing Callback Connection..."); doCallbackConnection(args.getCallbackPort(), t); } - + // Wait for startup if (args.isWaitStart()) { @@ -70,7 +70,7 @@ public class AgentInit e.printStackTrace(); } } - + // Setup shutdown hook Runtime.getRuntime().addShutdownHook(new Thread() { @@ -88,7 +88,7 @@ public class AgentInit AgentInit.class.notifyAll(); } - static synchronized void waitForServerPort() + static synchronized void waitForServerPort() { try { diff --git a/org.intrace/src/org/intrace/agent/ClassTransformer.java b/org.intrace/src/org/intrace/agent/ClassTransformer.java index 3ce193d..e74440a 100644 --- a/org.intrace/src/org/intrace/agent/ClassTransformer.java +++ b/org.intrace/src/org/intrace/agent/ClassTransformer.java @@ -44,7 +44,7 @@ public class ClassTransformer implements ClassFileTransformer * Pattern which matches nothing */ public static final String MATCH_NONE = ""; - + /** * Set of modified class names */ @@ -64,7 +64,7 @@ public class ClassTransformer implements ClassFileTransformer * Settings for this Transformer */ private final AgentSettings settings; - + /** * Marker indicating whether many classes are currently being updated */ @@ -72,7 +72,7 @@ public class ClassTransformer implements ClassFileTransformer /** * cTor - * + * * @param xiInst * @param xiEnableTracing * @param xiClassRegex @@ -92,14 +92,14 @@ public class ClassTransformer implements ClassFileTransformer /** * Generate and return instrumented class bytes. - * + * * @param xiClassName * @param classfileBuffer - * @param shouldInstrument + * @param shouldInstrument * @return Instrumented class bytes */ private byte[] getInstrumentedClassBytes(String xiClassName, - byte[] classfileBuffer, + byte[] classfileBuffer, boolean shouldInstrument) { try @@ -135,7 +135,7 @@ public class ClassTransformer implements ClassFileTransformer *
  • Class name doesn't match the regex *
  • Class is in a JAR and JAR instrumention is disabled * - * + * * @param klass * @param className * @param protectionDomain @@ -158,7 +158,7 @@ public class ClassTransformer implements ClassFileTransformer { return false; } - + // Don't sensitive classes if (isSensitiveClass(className)) { @@ -178,7 +178,7 @@ public class ClassTransformer implements ClassFileTransformer } return false; } - + // Don't modify classes which match the exclude regex if ((settings.getExcludeClassRegex() == null) || matches(settings.getExcludeClassRegex(), className)) @@ -206,7 +206,7 @@ public class ClassTransformer implements ClassFileTransformer // All checks passed - class can be instrumented return true; } - + private boolean matches(String[] strs, String target) { for (String str : strs) @@ -215,7 +215,7 @@ public class ClassTransformer implements ClassFileTransformer { continue; } - else if (str.equals(MATCH_ALL) || + else if (str.equals(MATCH_ALL) || target.contains(str)) { return true; @@ -226,7 +226,7 @@ public class ClassTransformer implements ClassFileTransformer private boolean isSensitiveClass(String className) { - return className.contains(".intrace.") || + return className.contains(".intrace.") || className.contains("objectweb.asm"); } @@ -250,29 +250,29 @@ public class ClassTransformer implements ClassFileTransformer Thread currentTh = Thread.currentThread(); UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler(); currentTh.setUncaughtExceptionHandler(AgentHelper.INSTRU_CRITICAL_BLOCK); - + try { String className = internalClassName.replace('/', '.'); ComparableClassName compclass = new ComparableClassName(className, loader); int modifiedSize = modifiedClasses.size(); int allClassesSize = allClasses.size(); - + boolean shouldInstrument = isToBeConsideredForInstrumentation(classBeingRedefined, loader, - className, protectionDomain); + className, protectionDomain); if (shouldInstrument || "java.lang.Thread".equals(className)) { // System.out.println("!! Instrumenting class: " + compclass); - + if (settings.saveTracedClassfiles()) { writeClassBytes(originalClassfile, internalClassName + "_src.class"); } - + byte[] newBytes; try { - newBytes = getInstrumentedClassBytes(className, + newBytes = getInstrumentedClassBytes(className, originalClassfile, shouldInstrument); } @@ -288,22 +288,22 @@ public class ClassTransformer implements ClassFileTransformer th.printStackTrace(); throw th; } - + if (settings.saveTracedClassfiles()) { writeClassBytes(newBytes, internalClassName + "_gen.class"); } - + modifiedClasses.add(compclass); - + sendStatusUpdate(modifiedSize, allClassesSize); - + return newBytes; } else { modifiedClasses.remove(compclass); - + sendStatusUpdate(modifiedSize, allClassesSize); return null; } @@ -318,14 +318,14 @@ public class ClassTransformer implements ClassFileTransformer { public final int modifiedSize; public final int allClassesSize; - + public StatusUpdate(int modifiedSize, int allClassesSize) { this.modifiedSize = modifiedSize; this.allClassesSize = allClassesSize; } } - + private static class StatusHolder { private StatusUpdate update; @@ -334,30 +334,31 @@ public class ClassTransformer implements ClassFileTransformer this.update = update; this.notifyAll(); } - + public synchronized StatusUpdate getStatus() throws InterruptedException { while (update == null) { this.wait(); } - + StatusUpdate retVal = update; update = null; - + return retVal; } } - + private class StatusUpdateThread extends InstruRunnable - { + { // Need more than 1 slot to allow for recursive status calls public final StatusHolder statusHolder = new StatusHolder(); + @Override public void runMethod() - { + { while (true) - { + { try { StatusUpdate update = statusHolder.getStatus(); @@ -376,7 +377,7 @@ public class ClassTransformer implements ClassFileTransformer } } } - + public StatusUpdateThread start() { Thread statusUpdateThread = new Thread(this); @@ -386,9 +387,9 @@ public class ClassTransformer implements ClassFileTransformer return this; } } - - private StatusUpdateThread statusUpdater = new StatusUpdateThread().start(); - + + private final StatusUpdateThread statusUpdater = new StatusUpdateThread().start(); + /** * Asynchronously send a status update to all connected clients. *

    @@ -452,7 +453,7 @@ public class ClassTransformer implements ClassFileTransformer /** * Toggle whether instrumentation is enabled - * + * * @param xiTracingEnabled */ public void setInstrumentationEnabled(boolean xiInstrumentationEnabled) @@ -484,8 +485,8 @@ public class ClassTransformer implements ClassFileTransformer /** * Handle a message and return a response. - * @param connection - * + * @param connection + * * @param message * @return Response or null if there is no response. */ @@ -546,7 +547,7 @@ public class ClassTransformer implements ClassFileTransformer *

    * Iterates over all loaded classes and retransforms those which we know we * have modified. - * + * * @param xiInst */ private Set getModifiedClasses() @@ -626,6 +627,12 @@ public class ClassTransformer implements ClassFileTransformer public void instrumentKlasses(Set klasses) { + if (!inst.isRetransformClassesSupported()) + { + System.out.println("## Retransform classes is not supported..."); + return; + } + if (klasses.size() == 0) { return; @@ -641,7 +648,7 @@ public class ClassTransformer implements ClassFileTransformer try { inst.retransformClasses(klass.klass); - + countNumClasses++; if ((countNumClasses % 10) == 0) { @@ -668,7 +675,7 @@ public class ClassTransformer implements ClassFileTransformer { broadcastProgress(count, total, false); } - + private void broadcastProgress(int count, int total, boolean done) { Map progressMap = new HashMap(); @@ -691,7 +698,7 @@ public class ClassTransformer implements ClassFileTransformer e.printStackTrace(); } } - + private void broadcastStatus(int count, int total) { Map progressMap = new HashMap(); @@ -726,7 +733,7 @@ public class ClassTransformer implements ClassFileTransformer /** * cTor - * + * * @param klassName * , ClassLoader klassloader */ @@ -865,7 +872,7 @@ public class ClassTransformer implements ClassFileTransformer /** * cTor - * + * * @param klass */ public ComparableClass(Class klass)