Disable retransform when not supported

This commit is contained in:
mchr3k 2012-01-03 21:27:22 +00:00
parent 5f6a992aea
commit 6745128b17
2 changed files with 65 additions and 58 deletions

View File

@ -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
{

View File

@ -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
* <li>Class name doesn't match the regex
* <li>Class is in a JAR and JAR instrumention is disabled
* </ul>
*
*
* @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.
* <p>
@ -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
* <p>
* Iterates over all loaded classes and retransforms those which we know we
* have modified.
*
*
* @param xiInst
*/
private Set<ComparableClass> getModifiedClasses()
@ -626,6 +627,12 @@ public class ClassTransformer implements ClassFileTransformer
public void instrumentKlasses(Set<ComparableClass> 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<String, String> progressMap = new HashMap<String, String>();
@ -691,7 +698,7 @@ public class ClassTransformer implements ClassFileTransformer
e.printStackTrace();
}
}
private void broadcastStatus(int count, int total)
{
Map<String, String> progressMap = new HashMap<String, String>();
@ -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)