de.hdu.pvs.crashfinder.instrument.MethodTracer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of crashFinder Show documentation
Show all versions of crashFinder Show documentation
A tool for localizing the software regression errors
The newest version!
package de.hdu.pvs.crashfinder.instrument;
import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Stack;
import de.hdu.pvs.crashfinder.util.Files;
import de.hdu.pvs.crashfinder.util.Globals;
/**
* An instrumentation class
* */
public class MethodTracer {
private static String CONTEXT_SEP = "%%CONTEXT%%";
public static int context_length = 0;
public static MethodTracer tracer = new MethodTracer();
private MethodTracer() {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.out.println("----------dumping traces to files-------");
synchronized (traceMap) {
StringBuilder sb = new StringBuilder();
for (String key : traceMap.keySet()) {
sb.append(key + AbstractInstrumenter.SEP
+ traceMap.get(key));
sb.append(Globals.lineSep);
}
try {
long time = System.currentTimeMillis();
System.out.println("At: " + time);
String fileName = "./trace_dump_" + time + ".txt";
File f = new File(fileName);
System.out.println("write to file: "
+ f.getAbsolutePath());
Files.writeToFile(sb.toString(), fileName);
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
Map traceMap = new LinkedHashMap();
Stack methodOnStack = new Stack();
// push a method call to the stack
public void pushEntry(String input) {
synchronized (this.methodOnStack) {
methodOnStack.push(input);
}
// System.out.println("push " + input + ":" +
// this.methodOnStack.toString());
}
// pop the method on the stack
public void popExit(String input) {
synchronized (this.methodOnStack) {
if (methodOnStack.isEmpty()) {
return;
}
String topMethod = methodOnStack.peek();
if (topMethod.equals(input)) {
methodOnStack.pop();
} else {
System.err
.println("Wrong in instrumentation, method not in stack: "
+ input);
while (!methodOnStack.isEmpty()) {
String top = methodOnStack.pop();
if (top.equals(input)) {
break;
}
}
}
}
// System.out.println("leave " + input + ":" +
// this.methodOnStack.toString());
}
public void popExceptionExit(String input) {
this.popExit(input);
}
public void trace(String input) {
// System.out.println(input);
synchronized (traceMap) {
// the format of line: PRE (or POST), config name, method as context
// we should record the call context, e.g, stacktrace
String line = input;
if (context_length > 0) {
line = input + CONTEXT_SEP
// + ExecutionContext.getCurrentContextAsString(context_length)
+ this.getTopContexts(context_length);
;
}
if (traceMap.containsKey(line)) {
traceMap.put(line, traceMap.get(line) + 1);
} else {
traceMap.put(line, 1L);
}
}
}
private String getTopContexts(int length) {
synchronized (this.methodOnStack) {
if (this.methodOnStack.size() < length) {
return this.methodOnStack.toString();
} else {
return this.methodOnStack.subList(
this.methodOnStack.size() - length,
this.methodOnStack.size()).toString();
}
}
}
}