diff --git a/JavassistTest/src/sample/A.java b/JavassistTest/src/sample/A.java new file mode 100644 index 0000000..50a856f --- /dev/null +++ b/JavassistTest/src/sample/A.java @@ -0,0 +1,10 @@ +package sample; + +public class A { + F f = new F(); + D d = new D(); + + public void m() { + d.passB(f, 10); + } +} diff --git a/JavassistTest/src/sample/A2.java b/JavassistTest/src/sample/A2.java deleted file mode 100644 index d05a07d..0000000 --- a/JavassistTest/src/sample/A2.java +++ /dev/null @@ -1,10 +0,0 @@ -package sample; - -public class A2 { - F f = new F(); - D d = new D(); - - public void m() { - d.passB(f, 10); - } -} diff --git a/JavassistTest/src/sample/F.java b/JavassistTest/src/sample/F.java index 2d04086..6de79b4 100644 --- a/JavassistTest/src/sample/F.java +++ b/JavassistTest/src/sample/F.java @@ -1,14 +1,9 @@ package sample; public class F extends B { - C c = null; + C c = new C(); public C getC() { - if (c == null) { - for (int n = 0; n < 3; n++) { - c = super.getC(); - } - } - return c; + return super.getC(); } } diff --git a/JavassistTest/src/sample/Main.java b/JavassistTest/src/sample/Main.java index 13862ea..b835818 100644 --- a/JavassistTest/src/sample/Main.java +++ b/JavassistTest/src/sample/Main.java @@ -7,8 +7,8 @@ */ public static void main(String[] args) { // TODO Auto-generated method stub - A2 a = new A2(); - A2 b = new A2(); + A a = new A(); + A b = new A(); a.m(); b.m(); } diff --git a/JavassistTest/src/tracer/Tracer.java b/JavassistTest/src/tracer/Tracer.java index dc4b908..9ae1bc5 100644 --- a/JavassistTest/src/tracer/Tracer.java +++ b/JavassistTest/src/tracer/Tracer.java @@ -24,18 +24,19 @@ import javassist.expr.MethodCall; public class Tracer { + private static int lineNo = 1; public static void main(String[] args) { - String packageName = "sample"; // �w�肵���p�b�P�[�W�����̑S�N���X�ɃC���X�g�D�������e�[�V�������s�� + String packageName = "sample"; // �w�肵���p�b�P�[�W�����̑S�N���X�ɃC���X�g�D�������e�[�V�������s�� ClassLoader loader = Thread.currentThread().getContextClassLoader(); URL resource = loader.getResource(packageName); File dir; try { - dir = new File( URLDecoder.decode(resource.getPath(), "UTF-8")); + dir = new File(URLDecoder.decode(resource.getPath(), "UTF-8")); for (String file : dir.list()) { if (file.endsWith(".class")) { String className = packageName + "." + file.replace(".class", ""); - classInstrumentation(className); + classInstrumentation(className); } } } catch (UnsupportedEncodingException e) { @@ -45,149 +46,188 @@ /** * �w�肵���N���X�ɃC���X�g�D�������e�[�V�������s���i���j - * @param className �N���X�� + * + * @param className + * �N���X�� */ private static void classInstrumentation(String className) { ClassPool cp = ClassPool.getDefault(); - CtClass cc; + CtClass cc; try { cc = cp.get(className); for (CtMethod m : cc.getDeclaredMethods()) { - ControlFlow cf = new ControlFlow(m); - String declaredClassName = cc.getName(); - String longName = m.getLongName(); - String methodSignature = m.getSignature(); - if ((m.getModifiers() & Modifier.STATIC) == 0) { - CtClass parameterClasses[] = m.getParameterTypes(); - String parameters = "\",{\""; - String delimiter = " + "; - int p = 1; - for (CtClass c: parameterClasses) { - if (!c.isPrimitive()) { - parameters += delimiter + "System.identityHashCode($" + p + ")"; - delimiter = " + \",\" + "; - } - p++; - } - // System.out.println("System.out.println(\"Method " + declaredClassName + "," + longName + ":\" + System.identityHashCode(this) + " + parameters + " + \"}:ThreadNo \" + Thread.currentThread().getId());"); - m.insertBefore("System.out.println(\"Method " + declaredClassName + "," + longName + ":\" + System.identityHashCode(this) + " + parameters + " + \"}:ThreadNo \" + Thread.currentThread().getId());"); - m.instrument(new ExprEditor() { - public void edit(FieldAccess f) throws CannotCompileException { - if (f.isReader()) { - f.replace("{$_ = $proceed(); System.out.println(\"FieldGet \" + System.identityHashCode($0) + \",\" + System.identityHashCode($_));}"); - } else { - f.replace("$proceed($$); System.out.println(\"FieldSet \" + System.identityHashCode($0) + \",\" + System.identityHashCode($1));"); - } - } - }); - m.insertAfter("System.out.println(\"Return:\" + System.identityHashCode($_));"); - // CodeConverter conv = new CodeConverter(); - // conv.replaceArrayAccess(cc, new ArrayAccessReplacementMethodNames() { - // @Override - // public String shortWrite() { - // return null; - // } - // @Override - // public String shortRead() { - // return null; - // } - // @Override - // public String objectWrite() { - // return null; - // } - // @Override - // public String objectRead() { - // return null; - // } - // @Override - // public String longWrite() { - // return null; - // } - // @Override - // public String longRead() { - // return null; - // } - // @Override - // public String intWrite() { - // return null; - // } - // @Override - // public String intRead() { - // return null; - // } - // @Override - // public String floatWrite() { - // return null; - // } - // @Override - // public String floatRead() { - // return null; - // } - // @Override - // public String doubleWrite() { - // return null; - // } - // @Override - // public String doubleRead() { - // return null; - // } - // @Override - // public String charWrite() { - // return null; - // } - // @Override - // public String charRead() { - // return null; - // } - // @Override - // public String byteOrBooleanWrite() { - // return null; - // } - // @Override - // public String byteOrBooleanRead() { - // return null; - // } - // }); - } - Block[] blocks = cf.basicBlocks(); - int block0 = m.getMethodInfo().getLineNumber(blocks[0].position()); - // int block1 = m.getMethodInfo().getLineNumber(blocks[1].position()); - // int block2 = m.getMethodInfo().getLineNumber(blocks[2].position()); - // int block3 = m.getMethodInfo().getLineNumber(blocks[3].position()); - // int block4 = m.getMethodInfo().getLineNumber(blocks[4].position()); - m.insertAt(block0, "System.out.println(\"block0:\" + " + block0 + ");"); - // m.insertAt(block1, "System.out.println(\"block1:\" + " + block1 + ");"); - // m.insertAt(block2, "System.out.println(\"block2:\" + " + block2 + ");"); - // m.insertAt(block3, "System.out.println(\"block3:\" + " + block3 + ");"); - // m.insertAt(block4, "System.out.println(\"block4:\" + " + block4 + ");"); - - - // int block0 = m.getMethodInfo().getLineNumber(blocks[0].position()); - // m.insertAt(block0, "System.out.println(\"block0\");"); - // m = cc.getDeclaredMethod("getC"); - // cf = new ControlFlow(m); - // blocks = cf.basicBlocks(); - // int block1 = m.getMethodInfo().getLineNumber(blocks[1].position()); - // m.insertAt(block1, "System.out.println(\"block1\");"); - // m = cc.getDeclaredMethod("getC"); - // cf = new ControlFlow(m); - // blocks = cf.basicBlocks(); - // int block2 = m.getMethodInfo().getLineNumber(blocks[2].position()); - // m.insertAt(block2, "System.out.println(\"block2\");"); - - // m.instrument(new ExprEditor() { - // public void edit(MethodCall m) throws CannotCompileException { - // if (m.getClassName().equals("Hello") - // && m.getMethodName().equals("say")) - // m.replace("$0.hi();"); - // } - // }); + ControlFlow cf = new ControlFlow(m); + String declaredClassName = cc.getName(); + String longName = m.getReturnType().getName() + " " + m.getLongName(); + String shortName = cc.getSimpleName() + "." + m.getName() + "()"; + String methodSignature = m.getSignature(); + + m.instrument(new ExprEditor() { + public void edit(FieldAccess f) throws CannotCompileException { + if (f.isReader()) { + f.replace( + "{$_ = $proceed(); System.out.println(\"FieldGet \" + System.identityHashCode($0) + \",\" + System.identityHashCode($_));}"); + } else { + f.replace( + "$proceed($$); System.out.println(\"FieldSet \" + System.identityHashCode($0) + \",\" + System.identityHashCode($1));"); + } + } + }); + + String methodOutput = ""; + String classOutput = ""; + String argsOutput = ""; + + String delimiter = "System.out.println(\"Args:\" + "; + CtClass parameterClasses[] = m.getParameterTypes(); + int p = 0; + for (CtClass c : parameterClasses) { + p++; + if (!c.isPrimitive()) { + argsOutput += delimiter + "$args[" + (p - 1) + "].getClass().getName() + " + "\":\" + System.identityHashCode($" + p + ")"; + } else { + argsOutput += delimiter + "$args[" + (p - 1) + "].getClass().getName() + " + "\":\" + $" + p; + } + delimiter = " + \":\" + "; + } + if (p > 0) { + argsOutput += " + \":Line 0:\" + \":ThreadNo \" + Thread.currentThread().getId());"; + } + + if ((m.getModifiers() & Modifier.STATIC) == 0) { + methodOutput = "System.out.println(\"Method \" + this.getClass().getName() + \"," + longName + + ":\" + System.identityHashCode(this) + \":Line 0:\" + System.nanoTime() + \":ThreadNo \" + Thread.currentThread().getId());"; + classOutput = "System.out.println(\"Class \" + this.getClass().getName() + \":\" + System.identityHashCode(this) + \":Line 0\" + \":ThreadNo \" + Thread.currentThread().getId());"; + } else { + longName = "static " + longName; + methodOutput = "System.out.println(\"Method " + declaredClassName + "," + longName + + ":\" + 0 + \":Line 0:\" + System.nanoTime() + \":ThreadNo \" + Thread.currentThread().getId());"; + classOutput = "System.out.println(\"Class " + declaredClassName + ":\" + 0 + \":Line 0\" + \":ThreadNo \" + Thread.currentThread().getId());"; + } + m.insertBefore("{" + methodOutput + classOutput + argsOutput + "}"); + m.insertAfter("if ($_ != null) {" + + "System.out.println(\"Return execution(" + shortName + "):\" + $_.getClass().getName() + \":\" + System.identityHashCode($_) + \":Line 0\" + \":ThreadNo \" + Thread.currentThread().getId());" + + "} else {" + + "System.out.println(\"Return execution(" + shortName + "):void:0\" + \":Line 0\" + \":ThreadNo \" + Thread.currentThread().getId());" + + "}"); + // CodeConverter conv = new CodeConverter(); + // conv.replaceArrayAccess(cc, new + // ArrayAccessReplacementMethodNames() { + // @Override + // public String shortWrite() { + // return null; + // } + // @Override + // public String shortRead() { + // return null; + // } + // @Override + // public String objectWrite() { + // return null; + // } + // @Override + // public String objectRead() { + // return null; + // } + // @Override + // public String longWrite() { + // return null; + // } + // @Override + // public String longRead() { + // return null; + // } + // @Override + // public String intWrite() { + // return null; + // } + // @Override + // public String intRead() { + // return null; + // } + // @Override + // public String floatWrite() { + // return null; + // } + // @Override + // public String floatRead() { + // return null; + // } + // @Override + // public String doubleWrite() { + // return null; + // } + // @Override + // public String doubleRead() { + // return null; + // } + // @Override + // public String charWrite() { + // return null; + // } + // @Override + // public String charRead() { + // return null; + // } + // @Override + // public String byteOrBooleanWrite() { + // return null; + // } + // @Override + // public String byteOrBooleanRead() { + // return null; + // } + // }); + // Block[] blocks = cf.basicBlocks(); + // int block0 = m.getMethodInfo().getLineNumber(blocks[0].position()); + // int block1 = + // m.getMethodInfo().getLineNumber(blocks[1].position()); + // int block2 = + // m.getMethodInfo().getLineNumber(blocks[2].position()); + // int block3 = + // m.getMethodInfo().getLineNumber(blocks[3].position()); + // int block4 = + // m.getMethodInfo().getLineNumber(blocks[4].position()); + //�@m.insertAt(block0, "System.out.println(\"block0:\" + " + block0 + ");"); + // m.insertAt(block1, "System.out.println(\"block1:\" + " + + // block1 + ");"); + // m.insertAt(block2, "System.out.println(\"block2:\" + " + + // block2 + ");"); + // m.insertAt(block3, "System.out.println(\"block3:\" + " + + // block3 + ");"); + // m.insertAt(block4, "System.out.println(\"block4:\" + " + + // block4 + ");"); + + // int block0 = + // m.getMethodInfo().getLineNumber(blocks[0].position()); + // m.insertAt(block0, "System.out.println(\"block0\");"); + // m = cc.getDeclaredMethod("getC"); + // cf = new ControlFlow(m); + // blocks = cf.basicBlocks(); + // int block1 = + // m.getMethodInfo().getLineNumber(blocks[1].position()); + // m.insertAt(block1, "System.out.println(\"block1\");"); + // m = cc.getDeclaredMethod("getC"); + // cf = new ControlFlow(m); + // blocks = cf.basicBlocks(); + // int block2 = + // m.getMethodInfo().getLineNumber(blocks[2].position()); + // m.insertAt(block2, "System.out.println(\"block2\");"); + + // m.instrument(new ExprEditor() { + // public void edit(MethodCall m) throws CannotCompileException + // { + // if (m.getClassName().equals("Hello") + // && m.getMethodName().equals("say")) + // m.replace("$0.hi();"); + // } + // }); } - cc.writeFile("bin"); - } catch (NotFoundException | BadBytecode | CannotCompileException | IOException e) { + cc.writeFile("bin"); + } catch (NotFoundException | BadBytecode | CannotCompileException | IOException e) { e.printStackTrace(); -// } catch (CannotCompileException | IOException e) { -// e.printStackTrace(); + // } catch (CannotCompileException | IOException e) { + // e.printStackTrace(); } }