Skip to content

Commit

Permalink
Implement issue #31
Browse files Browse the repository at this point in the history
  • Loading branch information
mchr3k committed Apr 13, 2014
1 parent 8f16c1e commit 3a1debc
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 21 deletions.
Binary file modified org.intrace/lib/intrace-agent.jar
Binary file not shown.
69 changes: 54 additions & 15 deletions org.intrace/src/org/intrace/agent/ClassTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import org.intrace.output.trace.TraceHandler;
import org.intrace.shared.AgentConfigConstants;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.commons.EmptyVisitor;

/**
* Uses ASM2 to transform class files to add Trace instrumentation.
Expand Down Expand Up @@ -139,13 +141,15 @@ private byte[] getInstrumentedClassBytes(String xiClassName,
* @param klass
* @param className
* @param protectionDomain
* @param originalClassfile
* @return True if the Class with name className should be instrumented.
*/
private boolean isToBeConsideredForInstrumentation(
Class<?> klass,
ClassLoader klassloader,
String className,
ProtectionDomain protectionDomain)
ProtectionDomain protectionDomain,
byte[] originalClassfile)
{
ComparableClassName compklass = new ComparableClassName(className,
klassloader);
Expand Down Expand Up @@ -195,18 +199,59 @@ private boolean isToBeConsideredForInstrumentation(
if ((settings.getClassRegex() == null)
|| !matches(settings.getClassRegex(), className))
{
if (settings.isVerboseMode())
// Actually we should modify if any of the interfaces match the regex
boolean matchedInterface = false;
for(String klassInterface : getInterfaces(className, originalClassfile))
{
TraceHandler.INSTANCE.writeTraceOutput("DEBUG: Ignoring class not matching the active include regex: "
+ className);
if ((settings.getClassRegex() != null)
&& matches(settings.getClassRegex(), klassInterface))
{
matchedInterface |= true;
}
}

if(!matchedInterface)
{
if (settings.isVerboseMode())
{
TraceHandler.INSTANCE.writeTraceOutput("DEBUG: Ignoring class not matching the active include regex: "
+ className);
}
return false;
}
return false;
}

// All checks passed - class can be instrumented
return true;
}

private String[] getInterfaces(String className, byte[] originalClassfile)
{
try
{
final String[][] interfaceNames = new String[1][];
ClassReader cr = new ClassReader(originalClassfile);
ClassVisitor cv = new EmptyVisitor() {
@Override
public void visit(int version, int access, String name,
String signature, String superName, String[] interfaces)
{
interfaceNames[0] = interfaces;
super.visit(version, access, name, signature, superName, interfaces);
}
};
cr.accept(cv, 0);
return interfaceNames[0];
}
catch (Throwable th)
{
System.err.println("Caught Throwable when trying to instrument: "
+ className);
th.printStackTrace();
return new String[0];
}
}

private boolean matches(String[] strs, String target)
{
for (String str : strs)
Expand Down Expand Up @@ -259,8 +304,9 @@ public byte[] transform(ClassLoader loader, String internalClassName,
int allClassesSize = allClasses.size();

boolean shouldInstrument = isToBeConsideredForInstrumentation(classBeingRedefined, loader,
className, protectionDomain);
if (shouldInstrument || "java.lang.Thread".equals(className))
className, protectionDomain,
originalClassfile);
if (shouldInstrument && !"java.lang.Thread".equals(className))
{
// System.out.println("!! Instrumenting class: " + compclass);

Expand Down Expand Up @@ -585,8 +631,6 @@ private Set<ComparableClass> getModifiedClasses()
* <li>Class is an annotation
* <li>Class is synthetic
* <li>Class is not modifiable
* <li>Class is rejected by
* {@link ClassTransformer#isToBeConsideredForInstrumentation(String, ProtectionDomain)}
* </ul>
*/
public Set<ComparableClass> getLoadedClassesForModification()
Expand Down Expand Up @@ -620,12 +664,7 @@ else if (!inst.isModifiableClass(loadedClass))
+ loadedClass.getCanonicalName());
}
}
else if (isToBeConsideredForInstrumentation(
loadedClass,
loadedClass.getClassLoader(),
loadedClass.getName(),
loadedClass
.getProtectionDomain()))
else
{
ComparableClass loadedKlass = new ComparableClass(loadedClass);
unmodifiedKlasses.add(loadedKlass);
Expand Down
6 changes: 6 additions & 0 deletions org.intrace/testsrc/example/ISomeKindOfInterface.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package example;

public interface ISomeKindOfInterface
{
public void shoutOut();
}
10 changes: 10 additions & 0 deletions org.intrace/testsrc/example/ImplWithTerribleName.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package example;

public class ImplWithTerribleName implements ISomeKindOfInterface
{
@Override
public void shoutOut()
{
System.out.println("Woohoo!");
}
}
13 changes: 7 additions & 6 deletions org.intrace/testsrc/example/TraceExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

public class TraceExample
{

private static Map<String,String> map = new HashMap<String, String>();
static
{
map.put("foo", "bar");
}

/**
* @param args
* @throws Exception
Expand All @@ -23,7 +23,7 @@ public static void main(String[] args)
try
{
otherMain(args[0]);
}
}
catch (Throwable ex)
{
ex.printStackTrace();
Expand All @@ -38,6 +38,7 @@ public static void otherMain(String arg) throws Exception
InnerTestClass.foo();
workMethod("foobar");
new InnerTestClass().boolMethod(true);
new ImplWithTerribleName().shoutOut();
}
}

Expand Down Expand Up @@ -72,7 +73,7 @@ private static String exceptionMethod()
}
catch (Exception ex)
{
return "seen exception";
return "seen exception";
}
return "no exception";
}
Expand All @@ -89,12 +90,12 @@ private void instanceFoo()
{
System.setProperty("a", "foobar");
}

private void boolMethod(boolean xiArg)
{
System.out.println(Boolean.toString(xiArg));
}

private static void foo()
{
System.setProperty("a", "bar");
Expand Down

0 comments on commit 3a1debc

Please sign in to comment.