diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/handlers/InstrumentationHandler.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/handlers/InstrumentationHandler.java index fafbaca..b4ae0db 100644 --- a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/handlers/InstrumentationHandler.java +++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/handlers/InstrumentationHandler.java @@ -47,16 +47,11 @@ if (outputPath.startsWith(projectPath)) { outputPath = outputPath.substring(projectPath.length()); } - System.out.println(projectLocation); - System.out.println(projectPath); - System.out.println(outputPath); String classPath = projectLocation + outputPath; cp.appendClassPath(classPath); // �C���X�g�D�������e�[�V�������s�� - if (!Tracer.isInitialized()) { - Tracer.initialize(new OutputStatementsGenerator(new JSONTraceGenerator()), cp); // �����ŏo�̓t�H�[�}�b�g���w�肷�� - } + Tracer.initialize(new OutputStatementsGenerator(new JSONTraceGenerator()), cp); // �����ŏo�̓t�H�[�}�b�g���w�肷�� Tracer.packageInstrumentation("", classPath + "/"); } catch (JavaModelException | NotFoundException e) { e.printStackTrace(); diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/OutputStatementsGenerator.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/OutputStatementsGenerator.java index 5731930..ad672c3 100644 --- a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/OutputStatementsGenerator.java +++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/OutputStatementsGenerator.java @@ -31,19 +31,26 @@ return generator; } - public String generateReplaceStatementsForFieldSet(CtClass cc, FieldAccess f, int line) { + public String generateReplaceStatementsForFieldSet(CtClass cc, FieldAccess f, int line) throws NotFoundException { String fieldName = "\"" + f.getClassName() + "." + f.getFieldName() + "\""; String containerClass = "(($0 != null)?$0.getClass().getName():\"" + cc.getName() + "\")"; String containerObject = "(($0 != null)?System.identityHashCode($0):0)"; - String valueClass = "(($1 != null)?$1.getClass().getName():\"---\")"; - String valueObject = "(($1 != null)?System.identityHashCode($1):0)"; + String valueClass; + String valueObject; + if (!f.getField().getType().isPrimitive()) { + valueClass = "(($1 != null)?$1.getClass().getName():\"---\")"; + valueObject = "(($1 != null)?System.identityHashCode($1):0)"; + } else { + valueClass = "\"" + f.getField().getType().getName() + "\""; // ��{�^�̏ꍇ�AgetClass()�ł��Ȃ����� + valueObject = "$1"; + } String threadId = "Thread.currentThread().getId()"; String lineNum = "\"" + line + "\""; String timeStamp = "System.nanoTime()"; return generator.generateReplaceStatementsForFieldSet(fieldName, containerClass, containerObject, valueClass, valueObject, threadId, lineNum, timeStamp); } - public String generateReplaceStatementsForFieldGet(CtClass cc, CtBehavior m, FieldAccess f, int line) { + public String generateReplaceStatementsForFieldGet(CtClass cc, CtBehavior m, FieldAccess f, int line) throws NotFoundException { String fieldName = "\"" + f.getClassName() + "." + f.getFieldName() + "\""; String thisClass; String thisObject; @@ -57,8 +64,15 @@ } String containerClass = "(($0 != null)?$0.getClass().getName():\"---\")"; String containerObject = "(($0 != null)?System.identityHashCode($0):0)"; - String valueClass = "(($_ != null)?$_.getClass().getName():\"---\")"; - String valueObject = "(($_ != null)?System.identityHashCode($_):0)"; + String valueClass; + String valueObject; + if (!f.getField().getType().isPrimitive()) { + valueClass = "(($_ != null)?$_.getClass().getName():\"---\")"; + valueObject = "(($_ != null)?System.identityHashCode($_):0)"; + } else { + valueClass = "\"" + f.getField().getType().getName() + "\""; // ��{�^�̏ꍇ�AgetClass()�ł��Ȃ����� + valueObject = "$_"; + } String threadId = "Thread.currentThread().getId()"; String lineNum = "\"" + line + "\""; String timeStamp = "System.nanoTime()"; @@ -222,7 +236,7 @@ thisClass = "this.getClass().getName()"; thisObject = "System.identityHashCode(this)"; } else { - returnedClass = "\"" + ((CtMethod)m).getReturnType().getName() +"\""; + returnedClass = "\"" + ((CtMethod)m).getReturnType().getName() +"\""; // ��{�^�̏ꍇ�AgetClass()�ł��Ȃ����� returnedObject = "$_"; thisClass = "this.getClass().getName()"; thisObject = "System.identityHashCode(this)"; @@ -235,7 +249,7 @@ thisClass = "$0.getClass().getName()"; thisObject = "System.identityHashCode($0)"; } else { - returnedClass = "\"" + ((CtMethod)m).getReturnType().getName() +"\""; + returnedClass = "\"" + ((CtMethod)m).getReturnType().getName() +"\""; // ��{�^�̏ꍇ�AgetClass()�ł��Ȃ����� returnedObject = "$_"; thisClass = "$0.getClass().getName()"; thisObject = "System.identityHashCode($0)"; diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/Tracer.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/Tracer.java index f3f9b45..39859c7 100644 --- a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/Tracer.java +++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/Tracer.java @@ -5,6 +5,7 @@ import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLDecoder; +import java.util.List; import javassist.CannotCompileException; import javassist.ClassPool; @@ -15,8 +16,10 @@ import javassist.CtMethod; import javassist.NotFoundException; import javassist.bytecode.BadBytecode; +import javassist.bytecode.LineNumberAttribute; import javassist.bytecode.analysis.ControlFlow; import javassist.bytecode.analysis.ControlFlow.Block; +import javassist.bytecode.analysis.ControlFlow.Catcher; import javassist.expr.ExprEditor; import javassist.expr.FieldAccess; import javassist.expr.MethodCall; @@ -47,7 +50,7 @@ URL resource = loader.getResource(""); try { String classPath = URLDecoder.decode(resource.getPath(), "UTF-8"); - packageInstrumentation("worstCase", classPath); // �w�肵���p�b�P�[�W���̑S�N���X�ɃC���X�g�D�������e�[�V�������s�� + packageInstrumentation("worstCase/", classPath); // �w�肵���p�b�P�[�W���̑S�N���X�ɃC���X�g�D�������e�[�V�������s�� } catch (UnsupportedEncodingException e) { e.printStackTrace(); } @@ -82,14 +85,6 @@ } } } - - /** - * �������ς݂�? - * @return �������ς�: true, ����ȊO: false - */ - public static boolean isInitialized() { - return (outputStatementsGenerator != null) && (cp != null) && (conv != null); - } /** * �w�肵���p�b�P�[�W���̃N���X�ɃC���X�g�D�������e�[�V�������s�� @@ -99,13 +94,13 @@ */ public static void packageInstrumentation(String packageName, String classPath) { File dir; - dir = new File(classPath + packageName.replace(".", "/")); + dir = new File(classPath + packageName); for (File file : dir.listFiles()) { if (file.isFile() && file.getName().endsWith(".class")) { - String className = packageName + file.getName().replace(".class", ""); + String className = packageName.replace("/", ".") + file.getName().replace(".class", ""); classInstrumentation(className, classPath); } else if (file.isDirectory()) { - packageInstrumentation(packageName + file.getName() + ".", classPath); + packageInstrumentation(packageName + file.getName() + "/", classPath); } } } @@ -119,7 +114,9 @@ public static void classInstrumentation(String className, String classPath) { try { CtClass cc = cp.get(className); - classInstrumentation(cc, classPath); +// cc.defrost(); +// cc.stopPruning(true); + if (!cc.isFrozen()) classInstrumentation(cc, classPath); } catch (NotFoundException | BadBytecode | CannotCompileException | IOException e) { e.printStackTrace(); } @@ -145,7 +142,12 @@ if (classPath.endsWith("/")) { classPath = classPath.substring(0, classPath.length() - 1); } - cc.writeFile(classPath); + System.out.println(classPath + ":" + cc.getName()); +// cc.rebuildClassFile(); + cc.getClassFile().compact(); // ���ꂪ�Ȃ��ƁA���s���� java.lang.ClassFormatError: Truncated class file �ŗ����� + cc.debugWriteFile(classPath); +// cc.defrost(); + cc.detach(); } } @@ -164,23 +166,66 @@ if (m instanceof CtMethod && !m.isEmpty()) { ControlFlow cf = new ControlFlow((CtMethod)m); blocks = cf.basicBlocks(); + List list = m.getMethodInfo().getCodeAttribute().getAttributes(); + LineNumberAttribute attr = null; + for (int i = 0; i < list.size(); i++) { + if (list.get(i) instanceof LineNumberAttribute){ + attr = (LineNumberAttribute)list.get(i); + break; + } + } + int[] lines = new int[blocks.length]; + for (int i = 0; i < blocks.length; i++) { + int pos = blocks[i].position(); + int line = m.getMethodInfo().getLineNumber(pos); + if (attr != null && pos != attr.toStartPc(line)) { + lines[i] = -1; + } else { + lines[i] = line; + } + } for (int i = blocks.length - 1; i >= 0; i--) { - int blockPos = m.getMethodInfo().getLineNumber(blocks[i].position()); - m.insertAt(blockPos, outputStatementsGenerator.generateInsertStatementsForBlockEntry((CtMethod)m, i, blocks[i], blockPos)); + for (int j = 0; j < i; j++) { + if (lines[j] == lines[i]) { + lines[i] = -1; + break; + } + if (blocks[j].catchers().length > 0) { + for (Catcher c: blocks[j].catchers()) { + if (m.getMethodInfo().getLineNumber(c.block().position()) == lines[i]) { + lines[i] = -1; + break; + } + } + if (lines[i] == i) break; + } + } + if (lines[i] != -1) { + String code = outputStatementsGenerator.generateInsertStatementsForBlockEntry((CtMethod)m, i, blocks[i], lines[i]); + try { + m.insertAt(lines[i], code); + } catch (CannotCompileException e) { + System.out.println(m.getLongName() + ":" + lines[i] + ":" + blocks[i].catchers().length + ":" + code); + } + } } } // ���\�b�h�{�̓��̃t�B�[���h�A�N�Z�X�ƃ��\�b�h�Ăяo����u�������� m.instrument(new ExprEditor() { public void edit(FieldAccess f) throws CannotCompileException { - if (f.isReader()) { - if (!f.getFieldName().contains("$")) { // AspectJ�ł� final local �ϐ�����̃Q�b�g�͖��������̂ŁA����ɍ��킹�ď��O���� - f.replace(outputStatementsGenerator.generateReplaceStatementsForFieldGet(cc, m, f, f.getLineNumber())); + try { + if (f.isReader()) { + if (!f.getFieldName().contains("$")) { // AspectJ�ł� final local �ϐ�����̃Q�b�g�͖��������̂ŁA����ɍ��킹�ď��O���� + f.replace(outputStatementsGenerator.generateReplaceStatementsForFieldGet(cc, m, f, f.getLineNumber())); + } + } else { + if (!f.getFieldName().contains("$")) { // ���̏������Ȃ��ƂȂ���������i�����t�B�[���h?�ւ̃Z�b�g�������āA������E���ė����Ă�?�j + f.replace(outputStatementsGenerator.generateReplaceStatementsForFieldSet(cc, f, f.getLineNumber())); + } } - } else { - if (!f.getFieldName().contains("$")) { // ���̏������Ȃ��ƂȂ���������i�����t�B�[���h?�ւ̃Z�b�g�������āA������E���ė����Ă�?�j - f.replace(outputStatementsGenerator.generateReplaceStatementsForFieldSet(cc, f, f.getLineNumber())); - } + } catch (NotFoundException e) { + e.printStackTrace(); } } public void edit(MethodCall c) throws CannotCompileException { @@ -240,5 +285,8 @@ m.insertBefore(outputStatementsGenerator.generateInsertBeforeStatementsForMethodBody(cc, m)); } } + if (m.getMethodInfo().getCodeAttribute() != null) { + m.getMethodInfo().getCodeAttribute().computeMaxStack(); // ���ꂪ�Ȃ��ƁA���s���� java.lang.VerifyError: Stack map does not match the one at exception handler... �ŗ����� + } } } diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/TracerClassLoader.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/TracerClassLoader.java index 2538b2b..fb0f897 100644 --- a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/TracerClassLoader.java +++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/TracerClassLoader.java @@ -13,10 +13,10 @@ @Override protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - if (!Tracer.isInitialized()) Tracer.initialize(new OutputStatementsGenerator(new JSONTraceGenerator())); // �����ŏo�̓t�H�[�}�b�g���w�肷�� + Tracer.initialize(new OutputStatementsGenerator(new JSONTraceGenerator())); // �����ŏo�̓t�H�[�}�b�g���w�肷�� // "java"�Ŏn�܂�p�b�P�[�W�̓V�X�e���n�Ȃ̂Ńf�t�H���g�̃N���X���[�_�[�ɔC���� - if (name.startsWith("java") || name.startsWith("sun.") || name.startsWith(Tracer.TRACER)) { + if (name.startsWith("java") || name.startsWith("sun.") || name.startsWith("com.sun.") || name.startsWith(Tracer.TRACER)) { return super.loadClass(name, resolve); }