diff --git a/src/main/java/gr/gousiosg/javacg/dyn/Instrumenter.java b/src/main/java/gr/gousiosg/javacg/dyn/Instrumenter.java index f04690c0..3acfc093 100644 --- a/src/main/java/gr/gousiosg/javacg/dyn/Instrumenter.java +++ b/src/main/java/gr/gousiosg/javacg/dyn/Instrumenter.java @@ -171,11 +171,11 @@ private void enhanceMethod(CtBehavior method, String className) methodName = ""; method.insertBefore("gr.gousiosg.javacg.dyn.MethodStack.push(\"" + className - + ":" + methodName + "\");"); + + ":" + methodName + "\",$args);");// ADDED: $args which is an object array of the parameters method.insertAfter("gr.gousiosg.javacg.dyn.MethodStack.pop();"); } private static void err(String msg) { //System.err.println("[JAVACG-DYN] " + msg); } -} \ No newline at end of file +} diff --git a/src/main/java/gr/gousiosg/javacg/dyn/MethodStack.java b/src/main/java/gr/gousiosg/javacg/dyn/MethodStack.java index 1da646dc..aa7d142d 100644 --- a/src/main/java/gr/gousiosg/javacg/dyn/MethodStack.java +++ b/src/main/java/gr/gousiosg/javacg/dyn/MethodStack.java @@ -77,7 +77,9 @@ public void run() { sb = new StringBuffer(); } - public static void push(String callname) throws IOException { + + public static void push(String callname, Object [] argM) throws IOException {// added the object array in to pass the parameters to the + // funciton in. if (threadid == -1) threadid = Thread.currentThread().getId(); @@ -94,8 +96,21 @@ public static void push(String callname) throws IOException { sb.setLength(0); sb.append(">[").append(stack.size()).append("]"); sb.append("[").append(Thread.currentThread().getId()).append("]"); - sb.append(callname).append("=").append(System.nanoTime()).append("\n"); + if (!stack.isEmpty()) { sb.append(stack.peek()); } + sb.append(" ---> ").append(callname).append("=").append(System.nanoTime()).append("\n");// added in stack peek so it will also print the calling class + + sb.append("Formal Param Types: "); + + for(Object ob : argM) + { + sb.append(" ").append(ob.getClass().getName()); // GET THE PARAMETERS AND PRINT THE TYPE. + } + + sb.append("\n"); + fw.write(sb.toString()); + + stack.push(callname); } @@ -108,9 +123,9 @@ public static void pop() throws IOException { String returnFrom = stack.pop(); sb.setLength(0); - sb.append("<[").append(stack.size()).append("]"); + sb.append("\n\n<[").append(stack.size()).append("]"); sb.append("[").append(Thread.currentThread().getId()).append("]"); - sb.append(returnFrom).append("=").append(System.nanoTime()).append("\n"); + sb.append(returnFrom).append("=").append(System.nanoTime()).append("\n\n"); fw.write(sb.toString()); } -} \ No newline at end of file +} diff --git a/src/main/java/gr/gousiosg/javacg/stat/JCallGraph.java b/src/main/java/gr/gousiosg/javacg/stat/JCallGraph.java index 4d19408d..bc3717d0 100644 --- a/src/main/java/gr/gousiosg/javacg/stat/JCallGraph.java +++ b/src/main/java/gr/gousiosg/javacg/stat/JCallGraph.java @@ -37,44 +37,65 @@ import org.apache.bcel.classfile.ClassParser; /** - * Constructs a callgraph out of a JAR archive. Can combine multiple archives - * into a single call graph. + * Constructs a callgraph out of a set of directories, classes and JAR archives. + * Can combine multiple archives into a single call graph. * * @author Georgios Gousios * */ public class JCallGraph { - public static void main(String[] args) { - ClassParser cp; - try { - for (String arg : args) { + public static void processClass(String class_name) throws IOException { + ClassParser cp = new ClassParser(class_name); + ClassVisitor visitor = new ClassVisitor(cp.parse()); + visitor.start(); + } + + public static void processClass(String jar_name, String class_name) throws IOException { + ClassParser cp = new ClassParser(jar_name,class_name); + ClassVisitor visitor = new ClassVisitor(cp.parse()); + visitor.start(); + } + + public static void processJar(JarFile jar) throws IOException { + Enumeration entries = jar.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + if (entry.isDirectory()) + continue; - File f = new File(arg); - - if (!f.exists()) { - System.err.println("Jar file " + arg + " does not exist"); - } - - JarFile jar = new JarFile(f); + if (!entry.getName().endsWith(".class")) + continue; - Enumeration entries = jar.entries(); - while (entries.hasMoreElements()) { - JarEntry entry = entries.nextElement(); - if (entry.isDirectory()) - continue; + processClass(jar.getName(),entry.getName()); + } + } - if (!entry.getName().endsWith(".class")) - continue; + public static void processFile(File file) { + try { + if (!file.exists()) + System.err.println("File " + file.getName() + " does not exist"); - cp = new ClassParser(arg,entry.getName()); - ClassVisitor visitor = new ClassVisitor(cp.parse()); - visitor.start(); - } + else if (file.isDirectory()) { + for (File dfile : file.listFiles()) + processFile(dfile); } + + else if (file.getName().endsWith(".jar")) + processJar(new JarFile(file)); + + else if (file.getName().endsWith(".class")) + processClass(file.getAbsolutePath()); + } catch (IOException e) { - System.err.println("Error while processing jar: " + e.getMessage()); + System.err.println("Error while processing file: " + e.getMessage()); e.printStackTrace(); } } + + public static void main(String[] args) { + for (String arg : args) { + processFile(new File(arg)); + } + } } diff --git a/src/main/java/gr/gousiosg/javacg/stat/MethodVisitor.java b/src/main/java/gr/gousiosg/javacg/stat/MethodVisitor.java index 4dd0821b..f8d2e9e6 100644 --- a/src/main/java/gr/gousiosg/javacg/stat/MethodVisitor.java +++ b/src/main/java/gr/gousiosg/javacg/stat/MethodVisitor.java @@ -48,7 +48,7 @@ public MethodVisitor(MethodGen m, JavaClass jc) { visitedClass = jc; mg = m; cp = mg.getConstantPool(); - format = "M:" + visitedClass.getClassName() + ":" + mg.getName() + "(" + argumentList(mg.getArgumentTypes()) + ")" + format = "M:" + visitedClass.getClassName() + ":" + mg.getName() + "(" + argumentList(mg.getArgumentTypes()) + "):%d" + " " + "(%s)%s:%s(%s)"; } @@ -84,27 +84,27 @@ private boolean visitInstruction(Instruction i) { @Override public void visitINVOKEVIRTUAL(INVOKEVIRTUAL i) { - System.out.println(String.format(format,"M",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); + System.out.println(String.format(format,i.getIndex(),"M",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); } @Override public void visitINVOKEINTERFACE(INVOKEINTERFACE i) { - System.out.println(String.format(format,"I",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); + System.out.println(String.format(format,i.getIndex(),"I",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); } @Override public void visitINVOKESPECIAL(INVOKESPECIAL i) { - System.out.println(String.format(format,"O",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); + System.out.println(String.format(format,i.getIndex(),"O",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); } @Override public void visitINVOKESTATIC(INVOKESTATIC i) { - System.out.println(String.format(format,"S",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); + System.out.println(String.format(format,i.getIndex(),"S",i.getReferenceType(cp),i.getMethodName(cp),argumentList(i.getArgumentTypes(cp)))); } @Override public void visitINVOKEDYNAMIC(INVOKEDYNAMIC i) { - System.out.println(String.format(format,"D",i.getType(cp),i.getMethodName(cp), + System.out.println(String.format(format,i.getIndex(),"D",i.getType(cp),i.getMethodName(cp), argumentList(i.getArgumentTypes(cp)))); } }