diff --git a/JavassistTest/src/tracer/Tracer.java b/JavassistTest/src/tracer/Tracer.java index 9ae1bc5..71a9460 100644 --- a/JavassistTest/src/tracer/Tracer.java +++ b/JavassistTest/src/tracer/Tracer.java @@ -11,7 +11,9 @@ import javassist.ClassPool; import javassist.CodeConverter; import javassist.CodeConverter.ArrayAccessReplacementMethodNames; +import javassist.CtBehavior; import javassist.CtClass; +import javassist.CtConstructor; import javassist.CtField; import javassist.CtMethod; import javassist.Modifier; @@ -24,7 +26,9 @@ import javassist.expr.MethodCall; public class Tracer { - private static int lineNo = 1; + public static int lineNo = 1; + private static final String lineAndThread = "\":Line \" + (tracer.Tracer.lineNo++) + \":ThreadNo \" + Thread.currentThread().getId()"; + private static final String line = "\":Line \" + (tracer.Tracer.lineNo++) + \":\""; public static void main(String[] args) { String packageName = "sample"; // �w�肵���p�b�P�[�W�����̑S�N���X�ɃC���X�g�D�������e�[�V�������s�� @@ -55,173 +59,11 @@ CtClass cc; try { cc = cp.get(className); - for (CtMethod m : cc.getDeclaredMethods()) { - 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();"); - // } - // }); + for (final CtConstructor c : cc.getConstructors()) { + methodInstrumentation(cc, c); + } + for (final CtMethod m : cc.getDeclaredMethods()) { + methodInstrumentation(cc, m); } cc.writeFile("bin"); } catch (NotFoundException | BadBytecode | CannotCompileException | IOException e) { @@ -231,4 +73,243 @@ } } + private static void methodInstrumentation(CtClass cc, final CtBehavior m) + throws BadBytecode, NotFoundException, CannotCompileException { +// ControlFlow cf = new ControlFlow(m); + final String declaredClassName = cc.getName(); + String methodSignature = m.getSignature(); + + m.instrument(new ExprEditor() { + public void edit(FieldAccess f) throws CannotCompileException { + if (f.isReader()) { + String thisOutput = ""; + if ((m.getModifiers() & Modifier.STATIC) == 0 && m instanceof CtMethod) { + thisOutput = "System.out.print(\"get:\" + this.getClass().getName() + \":\" + System.identityHashCode(this) + \":\"); "; + } else { + // static���\�b�h���R���X�g���N�^�̏ꍇ + thisOutput = "System.out.print(\"get:" + declaredClassName + ":0:\"); "; + } + f.replace("{$_ = $proceed(); " + + thisOutput + + "if ($0 != null) {" + // target + "System.out.print($0.getClass().getName() + \":\" + System.identityHashCode($0) + \":\"); " + + "} else {" + + "System.out.print(\"---:0:\"); " + + "} " + + "if ($_ != null) {" + // o + "System.out.println($_.getClass().getName() + \":\" + System.identityHashCode($_) + " + lineAndThread + ");" + + "} else {" + + "System.out.println(\"---:0\" + " + lineAndThread + ");" + + "} " + "}"); + } else { + f.replace("{$proceed($$); " + + "if ($0 != null) {" + // target + "System.out.print(\"set:\" + $0.getClass().getName() + \":\" + System.identityHashCode($0) + \":\"); " + + "} else {" + + "System.out.print(\"set:" + declaredClassName + ":0:\"); " + + "} " + + "if ($1 != null) {" + // o[0] + "System.out.println($1.getClass().getName() + \":\" + System.identityHashCode($1) + " + lineAndThread + ");" + + "} else {" + + "System.out.println(\"---:0\" + " + lineAndThread + ");" + + "}" + "}"); + } + } + }); + + String newOutput = ""; + String methodOutput = ""; + String classOutput = ""; + String argsOutput = ""; + String returnOutput = ""; + + String delimiter = "System.out.println(\"Args:\" + "; + CtClass parameterClasses[] = m.getParameterTypes(); + int p = 0; + for (CtClass c : parameterClasses) { + if (!c.isPrimitive()) { + argsOutput += delimiter + "$args[" + p + "].getClass().getName() + " + "\":\" + System.identityHashCode($" + (p + 1) + ")"; + } else { + argsOutput += delimiter + "$args[" + p + "].getClass().getName() + " + "\":\" + $" + (p + 1); + } + p++; + delimiter = " + \":\" + "; + } + if (p > 0) { + argsOutput += " + " + lineAndThread + ");"; + } + + String accessor = ""; + if ((m.getModifiers() & Modifier.PUBLIC) != 0) { + accessor = "public "; + } else if ((m.getModifiers() & Modifier.PRIVATE) != 0) { + accessor = "private "; + } else if ((m.getModifiers() & Modifier.PROTECTED) != 0) { + accessor = "protected "; + } + String longName = null; + if ((m.getModifiers() & Modifier.STATIC) != 0) { + // static���\�b�h�̏ꍇ + longName = accessor + "static " + m.getLongName(); + methodOutput = "System.out.println(\"Method " + declaredClassName + "," + longName + + ":\" + 0 + " + line + " + System.nanoTime() + \":ThreadNo \" + Thread.currentThread().getId());"; + classOutput = "System.out.println(\"Class " + declaredClassName + ":\" + 0 + " + lineAndThread + ");"; + } else if (m instanceof CtConstructor) { + // �R���X�g���N�^�̏ꍇ + longName = accessor + m.getLongName(); + newOutput = "System.out.println(\"New " + declaredClassName + ":\" + 0 + " + lineAndThread + ");"; + methodOutput = "System.out.println(\"Method " + declaredClassName + "," + longName + + ":\" + 0 + " + line + " + System.nanoTime() + \":ThreadNo \" + Thread.currentThread().getId());"; + classOutput = "System.out.println(\"Class " + declaredClassName + ":\" + 0 + " + lineAndThread + ");"; + } else { + // �ʏ�̃��\�b�h�̏ꍇ + longName = accessor + ((CtMethod)m).getReturnType().getName() + " " + m.getLongName(); + methodOutput = "System.out.println(\"Method \" + this.getClass().getName() + \"," + longName + + ":\" + System.identityHashCode(this) + " + line + " + System.nanoTime() + \":ThreadNo \" + Thread.currentThread().getId());"; + classOutput = "System.out.println(\"Class \" + this.getClass().getName() + \":\" + System.identityHashCode(this) + " + lineAndThread + ");"; + } + + String shortName = null; + if ((m.getModifiers() & Modifier.STATIC) != 0) { + // static���\�b�h�̏ꍇ + shortName = cc.getSimpleName() + "." + m.getName() + "()"; + returnOutput = "if ($_ != null) {" + + "System.out.print(\"Return execution(" + shortName + "):\" + $_.getClass().getName() + \":\" + System.identityHashCode($_) + \":\");" + + "} else {" + + "System.out.print(\"Return execution(" + shortName + "):void:0:\");" + + "} " + + "System.out.println(\"0\" + " + lineAndThread + ");"; + } else if (m instanceof CtConstructor) { + // �R���X�g���N�^�̏ꍇ + shortName = m.getName() + "()"; + returnOutput = "System.out.print(\"Return initialization(" + shortName + "):" + declaredClassName + ":\" + System.identityHashCode($0) + \":\");" + + "System.out.println(\"\" + System.identityHashCode($0) + " + lineAndThread + ");"; + } else { + // �ʏ�̃��\�b�h�̏ꍇ + shortName = cc.getSimpleName() + "." + m.getName() + "()"; + returnOutput = "if ($_ != null) {" + + "System.out.print(\"Return execution(" + shortName + "):\" + $_.getClass().getName() + \":\" + System.identityHashCode($_) + \":\");" + + "} else {" + + "System.out.print(\"Return execution(" + shortName + "):void:0:\");" + + "} " + + "System.out.println(\"\" + System.identityHashCode(this) + " + lineAndThread + ");"; + } + + + m.insertBefore("{" + newOutput + methodOutput + classOutput + argsOutput + "}"); + m.insertAfter("{" + returnOutput + "}"); + // 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();"); + // } + // }); + } + }