Skip to content

Commit

Permalink
several improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
dkarv committed Dec 10, 2017
1 parent 4e16836 commit 7daf24a
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ public class CallRecorder {
*/
static final Map<Long, CallGraph> GRAPHS = new HashMap<>();

public static void beforeMethod(String className, String methodName, int lineNumber) {
public static void beforeMethod(String className, String methodName, int lineNumber,
boolean isTest) {
try {
LOG.trace("beforeMethod: {}:{}#{}", className, methodName, lineNumber);
long threadId = Thread.currentThread().getId();
Expand All @@ -48,13 +49,14 @@ public static void beforeMethod(String className, String methodName, int lineNum
graph = new CallGraph(threadId);
GRAPHS.put(threadId, graph);
}
graph.called(new StackItem(className, methodName, lineNumber));
graph.called(new StackItem(className, methodName, lineNumber, isTest));
} catch (Throwable e) {
LOG.error("Error in beforeMethod", e);
}
}

public static void afterMethod(String className, String methodName, int lineNumber) {
public static void afterMethod(String className, String methodName, int lineNumber,
boolean isTest) {
try {
LOG.trace("afterMethod: {}:{}#{}", className, methodName, lineNumber);
long threadId = Thread.currentThread().getId();
Expand All @@ -63,7 +65,7 @@ public static void afterMethod(String className, String methodName, int lineNumb
// not interesting
return;
}
graph.returned(new StackItem(className, methodName, lineNumber));
graph.returned(new StackItem(className, methodName, lineNumber, isTest));
} catch (Throwable e) {
LOG.error("Error in afterMethod", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

public class FieldAccessRecorder {
private static final Logger LOG = new Logger(FieldAccessRecorder.class);
Expand All @@ -54,7 +53,8 @@ public class FieldAccessRecorder {
needCombined = combined;
}

public static void write(String fromClass, String fromMethod, int lineNumber, String fieldClass, String fieldName) {
public static void write(String fromClass, String fromMethod, int lineNumber, String fieldClass,
String fieldName) {
try {
LOG.trace("Write to {}::{} from {}::{}", fieldClass, fieldName, fromClass, fromMethod);
long threadId = Thread.currentThread().getId();
Expand All @@ -63,13 +63,15 @@ public static void write(String fromClass, String fromMethod, int lineNumber, St
graph = new DataDependenceGraph(threadId);
GRAPHS.put(threadId, graph);
}
graph.addWrite(new StackItem(fromClass, fromMethod, lineNumber), fieldClass + "::" + fieldName);
graph.addWrite(new StackItem(fromClass, fromMethod, lineNumber, false),
fieldClass + "::" + fieldName);
} catch (Exception e) {
LOG.error("Error in write", e);
}
}

public static void read(String fromClass, String fromMethod, int lineNumber, String fieldClass, String fieldName) {
public static void read(String fromClass, String fromMethod, int lineNumber, String fieldClass,
String fieldName) {
try {
LOG.trace("Read to {}::{} from {}::{}", fieldClass, fieldName, fromClass, fromMethod);
long threadId = Thread.currentThread().getId();
Expand All @@ -80,10 +82,10 @@ public static void read(String fromClass, String fromMethod, int lineNumber, Str
}
if (needCombined) {
CallGraph callGraph = CallRecorder.GRAPHS.get(threadId);
graph.addRead(new StackItem(fromClass, fromMethod, lineNumber), fieldClass + "::" +
graph.addRead(new StackItem(fromClass, fromMethod, lineNumber, false), fieldClass + "::" +
fieldName, callGraph);
} else {
graph.addRead(new StackItem(fromClass, fromMethod, lineNumber), fieldClass + "::" +
graph.addRead(new StackItem(fromClass, fromMethod, lineNumber, false), fieldClass + "::" +
fieldName, null);
}
} catch (Exception e) {
Expand Down
46 changes: 42 additions & 4 deletions jdcallgraph/src/main/java/com/dkarv/jdcallgraph/Tracer.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,14 @@ public class Tracer implements ClassFileTransformer {
* @throws IOException io error
* @throws IllegalAccessException problem loading the config options
*/
public static void premain(String argument, Instrumentation instrumentation) throws IOException, IllegalAccessException {
public static void premain(String argument, Instrumentation instrumentation)
throws IOException, IllegalAccessException {
ShutdownHook.init();
if (argument != null) {
new ConfigReader(new File(argument)).read();
} else {
System.err.println("You did not specify a config file. Will use the default config options instead.");
System.err.println(
"You did not specify a config file. Will use the default config options instead.");
}


Expand Down Expand Up @@ -106,7 +108,9 @@ public byte[] transform(ClassLoader loader, String className, Class clazz,

if (enhanceClass) {
byte[] b = enhanceClass(bytes);
if (b != null) return b;
if (b != null) {
return b;
}
}
return bytes;
}
Expand Down Expand Up @@ -184,9 +188,23 @@ void enhanceMethod(CtBehavior method, String className)
method.instrument(fieldTracer);
}

boolean isTest = false;
MethodInfo info = method.getMethodInfo2();
if (info.isMethod() && !Modifier.isStatic(info.getAccessFlags())) {
// FIXME check if class extends Testcase
isTest = checkTestAnnotation(method);
}

int lineNumber = getLineNumber(method);

String args = '"' + className + '"' + ',' + '"' + mName + '"' + ',' + lineNumber;
String args;
if (isTest) {
LOG.debug("subtest detection enabled on {}::{}", className, mName);
args =
"getClass().getCanonicalName()" + ',' + '"' + mName + '"' + ',' + lineNumber + ',' + true;
} else {
args = '"' + className + '"' + ',' + '"' + mName + '"' + ',' + lineNumber + ',' + false;
}

String srcBefore = "com.dkarv.jdcallgraph.CallRecorder.beforeMethod(" + args + ");";
String srcAfter = "com.dkarv.jdcallgraph.CallRecorder.afterMethod(" + args + ");";
Expand All @@ -199,6 +217,26 @@ void enhanceMethod(CtBehavior method, String className)
//}
}

private static boolean checkTestAnnotation(CtBehavior method) {
MethodInfo mi = method.getMethodInfo2();
AnnotationsAttribute attr =
((AnnotationsAttribute) mi.getAttribute(AnnotationsAttribute.invisibleTag));
if (attr != null) {
javassist.bytecode.annotation.Annotation anno = attr.getAnnotation("org.junit.Test");
if (anno != null) {
return true;
}
}


attr = ((AnnotationsAttribute) mi.getAttribute(AnnotationsAttribute.visibleTag));
if (attr == null) {
return false;
}
javassist.bytecode.annotation.Annotation anno = attr.getAnnotation("org.junit.Test");
return anno != null;
}

public static int getLineNumber(CtBehavior method) {
return method.getMethodInfo().getLineNumber(0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,11 @@ public void returned(StackItem method) throws IOException {
}
}
if (removed != 1) {
LOG.error("Error when method {} returned:", method);
LOG.error("Removed {} entries. Stack trace {}", removed, trace);
LOG.warn("Error when method {} returned:", method);
LOG.warn("Removed {} entries. Stack trace {}", removed, trace);
}
if (!found) {
LOG.error("Couldn't find the returned method call on stack");
LOG.warn("Couldn't find the returned method call on stack");
}
if (calls.isEmpty()) {
for (GraphWriter w : writers) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,24 @@ public class StackItem {
private final String methodName;
private final int lineNumber;

private final boolean test;

private final String formatted;

public StackItem(String className, String methodName, int lineNumber) {
public StackItem(String className, String methodName, int lineNumber, boolean test) {
this.className = className;
this.methodName = methodName;
this.lineNumber = lineNumber;

this.test = test;

this.formatted = Formatter.format(this);
}

public StackItem(String className, String methodName, int lineNumber) {
this(className, methodName, lineNumber, false);
}

public String getClassName() {
return className;
}
Expand All @@ -52,6 +60,10 @@ public int getLineNumber() {
return lineNumber;
}

public boolean isTest() {
return test;
}

@Override
public String toString() {
return formatted;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,21 @@ public void start(String identifier) throws IOException {

@Override
public void node(StackItem method) throws IOException {
currentItem = method;
if (method.isTest()) {
currentItem = method;
}
}

@Override
public void edge(StackItem from, StackItem to) throws IOException {
Set<StackItem> list = usedIn.get(to);
if (list == null) {
list = new HashSet<>();
usedIn.put(to, list);
if (currentItem != null) {
Set<StackItem> list = usedIn.get(to);
if (list == null) {
list = new HashSet<>();
usedIn.put(to, list);
}
list.add(currentItem);
}
list.add(currentItem);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

public class CsvTraceFileWriter implements GraphWriter {
FileWriter writer;
private boolean interested = true;

private final Set<StackItem> trace = new HashSet<>();

Expand All @@ -44,13 +45,16 @@ public void start(String identifier) throws IOException {

@Override
public void node(StackItem method) throws IOException {
writer.append(method.toString());
trace.clear();
interested = method.isTest();
if (interested) {
writer.append(method.toString());
}
}

@Override
public void edge(StackItem from, StackItem to) throws IOException {
if (!trace.contains(to)) {
if (interested && !trace.contains(to)) {
writer.append(';');
writer.append(to.toString());
trace.add(to);
Expand All @@ -64,7 +68,9 @@ public void edge(StackItem from, StackItem to, String label) throws IOException

@Override
public void end() throws IOException {
writer.append('\n');
if (interested) {
writer.append('\n');
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public void before() throws IOException, NotFoundException, CannotCompileExcepti
}

private String expected(String cName, String mName) {
String args = '"' + cName + '"' + ',' + '"' + mName + '"' + ',' + lineNumber;
String args = '"' + cName + '"' + ',' + '"' + mName + '"' + ',' + lineNumber + ",false";
return "com.dkarv.jdcallgraph.CallRecorder.beforeMethod(" + args + ");";
}

Expand Down

0 comments on commit 7daf24a

Please sign in to comment.