diff --git a/org.ntlab.reverseDebugger/.settings/org.eclipse.jdt.core.prefs b/org.ntlab.reverseDebugger/.settings/org.eclipse.jdt.core.prefs index 11f6e46..980b98c 100644 --- a/org.ntlab.reverseDebugger/.settings/org.eclipse.jdt.core.prefs +++ b/org.ntlab.reverseDebugger/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,12 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.source=1.7 diff --git a/org.ntlab.reverseDebugger/META-INF/MANIFEST.MF b/org.ntlab.reverseDebugger/META-INF/MANIFEST.MF index d51ce53..0221e87 100644 --- a/org.ntlab.reverseDebugger/META-INF/MANIFEST.MF +++ b/org.ntlab.reverseDebugger/META-INF/MANIFEST.MF @@ -9,6 +9,7 @@ org.eclipse.debug.core, org.eclipse.jdt.debug, org.eclipse.jdt.core;bundle-version="3.10.2", - org.eclipse.jdt.ui;bundle-version="3.10.2" + org.eclipse.jdt.ui;bundle-version="3.10.2", + org.ntlab.traceCollector Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy diff --git a/org.ntlab.reverseDebugger/plugin.xml b/org.ntlab.reverseDebugger/plugin.xml index fe25aa0..ebd68a0 100644 --- a/org.ntlab.reverseDebugger/plugin.xml +++ b/org.ntlab.reverseDebugger/plugin.xml @@ -23,21 +23,21 @@ @@ -46,10 +46,16 @@ + + + + diff --git a/org.ntlab.reverseDebugger/speedResult.csv b/org.ntlab.reverseDebugger/speedResult.csv new file mode 100644 index 0000000..06a88c1 --- /dev/null +++ b/org.ntlab.reverseDebugger/speedResult.csv @@ -0,0 +1,64 @@ +!SESSION 2018-09-21 14:34:47.545 ----------------------------------------------- +eclipse.buildId=4.4.2.M20150204-1700 +java.version=1.8.0_144 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=ja_JP +Framework arguments: -product org.eclipse.platform.ide +Command-line arguments: -product org.eclipse.platform.ide -data C:\Users\student\workspace/../runtime-EclipseApplication -dev file:C:/Users/student/workspace/.metadata/.plugins/org.eclipse.pde.core/Eclipse Application/dev.properties -os win32 -ws win32 -arch x86_64 -consoleLog + +!ENTRY org.eclipse.core.resources 2 10035 2018-09-21 14:34:50.118 +!MESSAGE The workspace exited with unsaved changes in the previous session; refreshing workspace to recover changes. + +!ENTRY org.eclipse.egit.ui 2 0 2018-09-21 14:35:00.050 +!MESSAGE Warning: EGit couldn't detect the installation path "gitPrefix" of native Git. Hence EGit can't respect system level +Git settings which might be configured in ${gitPrefix}/etc/gitconfig under the native Git installation directory. +The most important of these settings is core.autocrlf. Git for Windows by default sets this parameter to true in +this system level configuration. The Git installation location can be configured on the +Team > Git > Configuration preference page's 'System Settings' tab. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.egit.ui 2 0 2018-09-21 14:35:00.066 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\student'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +C:/Users/student/runtime-EclipseApplication/ObjectFlowTest/bin:Account +C:/Users/student/runtime-EclipseApplication/ObjectFlowTest/bin:Bank +C:/Users/student/runtime-EclipseApplication/ObjectFlowTest/bin:Company +C:/Users/student/runtime-EclipseApplication/ObjectFlowTest/bin:Main +C:/Users/student/runtime-EclipseApplication/ObjectFlowTest/bin:Money +C:/Users/student/runtime-EclipseApplication/ObjectFlowTest/bin:Person +C:/Users/student/runtime-EclipseApplication/ObjectFlowTest/bin:Stream +classpath[0] = C:\Users\student\runtime-EclipseApplication\ObjectFlowTest\bin +classpath[1] = C:\Users\student\Downloads\eclipse-rcp-luna-SR2-win32-x86_64\eclipse\..\..\..\git\org.ntlab.traceCollector\org.ntlab.traceCollector\bin\ +classpath[2] = C:\Users\student\Downloads\eclipse-rcp-luna-SR2-win32-x86_64\eclipse\..\..\..\git\org.ntlab.traceCollector\org.ntlab.traceCollector\javassist.jar +classpath[3] = C:\Users\student\Downloads\eclipse-rcp-luna-SR2-win32-x86_64\eclipse\..\..\..\git\org.ntlab.reverseDebugger\org.ntlab.reverseDebugger\bin\ +Main (2):org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget@3ed15147 +threadId = "1" +targetSignature: void Stream.print(Account) + +ReverseDebugger: +Exp (RD),36943787 +Exp (RD),26401389 +Exp (RD),25245539 +Exp (RD),18481762 +Exp (RD),21961946 +Exp (RD),24472604 +Exp (RD),22119848 +Exp (RD),19258645 +Exp (RD),25412917 +Exp (RD),20806885 + +TraceCollector: +Exp (TC),27179852 +Exp (TC),2595136 +Exp (TC),2990684 +Exp (TC),2403285 +Exp (TC),2804359 +Exp (TC),2524870 +Exp (TC),2853308 +Exp (TC),3163588 +Exp (TC),3174641 +Exp (TC),3058582 + diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/DebuggingControlAction.java b/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/DebuggingControlAction.java index 127dc87..a63c5c4 100644 --- a/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/DebuggingControlAction.java +++ b/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/DebuggingControlAction.java @@ -32,7 +32,9 @@ import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkbenchWindowActionDelegate; import org.eclipse.ui.PartInitException; -import org.ntlab.reversedebugger.ObjectFlowAliases; +import org.ntlab.reverseDebugger.ObjectFlowAliases; +import org.ntlab.reverseDebugger.OnlineTraceAnalyzer; +import org.ntlab.reverseDebugger.OnlineTraceAnalyzerCallTester; import com.sun.jdi.AbsentInformationException; import com.sun.jdi.BooleanValue; @@ -170,10 +172,16 @@ // �X�s�[�h�v���Ɣ�r SpeedTester st = new SpeedTester(); st.countMethodExecutionTest(vm, thread); + + // �݌v�ύX�ɂ��ꎟ��͗p�̃R�[�h(�^�[�Q�b�g����VM��Ŏ��s����OnlineTraceAnalyzer�N���X�֘A�̃��\�b�h)���Ăяo�����߂̉��R�[�h +// OnlineTraceAnalyzerCallTester analyzerCallTester = new OnlineTraceAnalyzerCallTester(); +// analyzerCallTester.test1(vm, thread); } /** * �I�����C����͒���traceCollector��TraceJSON#getObjectFlow()���Ăяo�����̃R�[�h + * 2018/9/16�NjL �����炩��objectFlow���Ăяo���K�v�͂Ȃ��Ȃ������߂����s�v�ȃR�[�h�ƍl���Ă悢 + * �݌v�ύX���s�������ߌĂяo���ƃG���[���������邩������Ȃ�(�����s�v�ȃR�[�h�̂��߃e�X�g���Ă��Ȃ�) * @param vm * @param thread * @param threadInstance @@ -190,8 +198,10 @@ int statementsSize = ((IntegerValue)callInstanceMethod(vm, thread, methodName, (ObjectReference)statements)).value(); // �f�o�b�K�Ŏ~�߂Ă���n�_�ɊY�����郁�\�b�h���s����, �X�^�[�g�ƂȂ���̃G�C���A�X�̃��X�g���擾���ĕ\������ - String packageName = "org.ntlab.traceCollector.tracer.trace"; - String className = "TraceJSON"; +// String packageName = "org.ntlab.traceCollector.tracer.trace"; +// String className = "TraceJSON"; + String packageName = "org.ntlab.reverseDebugger"; + String className = "OnlineTraceAnalyzer"; methodName = "findAllStartAlias"; Value startAliasList = callStaticMethod(vm, thread, packageName, className, methodName, methodExecution); methodName = "size"; diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/MethodCaller.java b/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/MethodCaller.java index 8ed4e37..3e9e5cf 100644 --- a/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/MethodCaller.java +++ b/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/MethodCaller.java @@ -1,8 +1,13 @@ package org.ntlab.debuggingControl; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.eclipse.jdi.TimeoutException; +import org.eclipse.jdt.core.Signature; + +import com.sun.jdi.ClassLoaderReference; import com.sun.jdi.ClassNotLoadedException; import com.sun.jdi.ClassType; import com.sun.jdi.IncompatibleThreadStateException; @@ -70,7 +75,19 @@ */ public Value callStaticMethod(String packageName, String className, String methodName, Value... args) throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { - List classes = vm.classesByName(packageName + "." + className); // �N���X�� (���S���薼) + String fqcn = packageName + "." + className; + List classes = vm.classesByName(fqcn); // �N���X�� (���S����N���X��) + + // ���Y�N���X���^�[�Q�b�gVM��Ń��[�h����Ă��Ȃ��ꍇ��, JDI��p���ă^�[�Q�b�gJVM��Ń��t���N�V�����ɂ�铖�Y�N���X�̃��[�h�����s���� + if (classes.isEmpty()) { + List list = vm.classesByName("java.lang.Class"); + ClassType type = (ClassType)list.get(0); + List methodsByName = type.methodsByName("forName"); + List argList = new ArrayList<>(); + argList.add(vm.mirrorOf(fqcn)); + type.invokeMethod(thread, methodsByName.get(0), argList, thread.INVOKE_SINGLE_THREADED); + classes = vm.classesByName(fqcn); // �N���X�� (���S����N���X��) + } ClassType type = (ClassType)classes.get(0); List methodsByName = type.methodsByName(methodName); List argList = Arrays.asList(args); // ���\�b�h�ɓn�������̃��X�g diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/SpeedTester.java b/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/SpeedTester.java index 4c63c6b..44be243 100644 --- a/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/SpeedTester.java +++ b/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/SpeedTester.java @@ -14,6 +14,7 @@ public class SpeedTester { private static final String TRACE = "org.ntlab.traceCollector.tracer.trace"; + private static final String ANALYZER = "org.ntlab.reverseDebugger"; public void countMethodExecutionTest(VirtualMachine vm, ThreadReference thread) { MethodCaller mc = new MethodCaller(vm, thread); @@ -32,7 +33,7 @@ // �ꎟ��͂̒T��������, �^�[�Q�b�g�v���O�����ɖ��ߍ���TraceCollector���ɍ쐬�����ꍇ�ł̏������Ԍv�� System.out.println(); System.out.println("TraceCollector:"); - test(mc, roots, targetSignature, SpeedTestType.TRACE_COLLECTOR, LOOP); + test(mc, roots, targetSignature, SpeedTestType.TRACE_COLLECTOR, LOOP); } catch (InvalidTypeException | ClassNotLoadedException | InvocationException | IncompatibleThreadStateException e) { e.printStackTrace(); @@ -42,7 +43,7 @@ private void test(MethodCaller mc, ObjectReference roots, String targetSignature, SpeedTestType type, final int LOOP) throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { int count = 0; - long beforeTime = 0, afterTime = 0, executionTime, sumTime = 0, bestTime = -1, worstTime = -1; + long beforeTime = 0, afterTime = 0; for (int i = 0; i < LOOP; i++) { mc.setObj(roots); switch (type) { @@ -57,23 +58,17 @@ afterTime = System.nanoTime(); break; } - executionTime = afterTime - beforeTime; - System.out.print("count: " + count + " "); - System.out.println(String.format("Time%-2d: %10d nsec", (i + 1), executionTime)); - sumTime += (executionTime); - bestTime = (bestTime < 0 || executionTime < bestTime) ? executionTime : bestTime; - worstTime = (worstTime < 0 || executionTime > worstTime) ? executionTime : worstTime; + System.out.println("Exp " + "(" + type.getTypeName() + ")," + (afterTime - beforeTime)); } - System.out.println(String.format("%-12s: %10d nsec", "BestTime", bestTime)); - System.out.println(String.format("%-12s: %10d nsec", "WorstTime", worstTime)); - System.out.println(String.format("%-12s: %10d nsec", "AverageTime", (sumTime / LOOP))); } private int countMethodExecutionInTraceCollector(MethodCaller mc, String targetSignture, int count, String indent) throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { VirtualMachine vm = mc.getVm(); String methodName = "countMethodExecutionInTraceCollector"; - return ((IntegerValue)mc.callStaticMethod(TRACE, "TraceJSON", methodName, mc.getObj(), +// return ((IntegerValue)mc.callStaticMethod(TRACE, "TraceJSON", methodName, mc.getObj(), +// vm.mirrorOf(targetSignture), vm.mirrorOf(count), vm.mirrorOf(indent))).value(); + return ((IntegerValue)mc.callStaticMethod(ANALYZER, "OnlineTraceAnalyzer", methodName, mc.getObj(), vm.mirrorOf(targetSignture), vm.mirrorOf(count), vm.mirrorOf(indent))).value(); } @@ -101,8 +96,19 @@ } return count; } - + private enum SpeedTestType { - REVERSE_DEBUGGER, TRACE_COLLECTOR; - } + REVERSE_DEBUGGER, TRACE_COLLECTOR; + + public String getTypeName() { + switch (this) { + case REVERSE_DEBUGGER: + return "RD"; + case TRACE_COLLECTOR: + return "TC"; + default: + return ""; + } + } + } } diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/Alias.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/Alias.java new file mode 100644 index 0000000..b50e6a9 --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/Alias.java @@ -0,0 +1,215 @@ +package org.ntlab.reverseDebugger; + +import java.util.ArrayList; + +import org.ntlab.traceCollector.tracer.trace.ArrayAccess; +import org.ntlab.traceCollector.tracer.trace.ArrayCreate; +import org.ntlab.traceCollector.tracer.trace.ArrayUpdate; +import org.ntlab.traceCollector.tracer.trace.FieldAccess; +import org.ntlab.traceCollector.tracer.trace.FieldUpdate; +import org.ntlab.traceCollector.tracer.trace.MethodExecution; +import org.ntlab.traceCollector.tracer.trace.MethodInvocation; +import org.ntlab.traceCollector.tracer.trace.ObjectReference; +import org.ntlab.traceCollector.tracer.trace.Statement; +import org.ntlab.traceCollector.tracer.trace.Trace; +import org.ntlab.traceCollector.tracer.trace.TracePoint; + +/** + * �I�u�W�F�N�g�̎Q�Ə��(�G�C���A�X)��\���N���X + * @author Isitani + * + */ +public class Alias { + private String objectId; + private TracePoint occurrencePoint; // ���Y�I�u�W�F�N�g�̎Q�Ƃ��s���Ă�����s�ӏ��ɑΉ�����TracePoint + /** + * ���Y�I�u�W�F�N�g�̎Q�Ƃ�TracePoint�ɂ����Ăǂ��Ɍ���Ă��邩��\��
+ * 0 �t�B�[���h�A�N�Z�X���̃R���e�i �������� ���\�b�h�Ăяo�����̃��V�[�o
+ * 1, 2, 3 �c�c n �t�B�[���h�A�N�Z�X���̃t�B�[���h(1) �������� ���\�b�h�Ăяo������n�Ԗڂ̎����� (1���珇�Ԃ�)
+ * -1 ���\�b�h�Ăяo�����̖߂�l
+ *
+ * ��1: d = a.m(b, c);
+ *
+ * ��1�̎��s���ɂ�����, a�̓��\�b�h�Ăяo���̃��V�[�o�Ȃ̂�0, b�̓��\�b�h�Ăяo����1�Ԗڂ̎������Ȃ̂�1,
+ * c�̓��\�b�h�Ăяo����2�Ԗڂ̎������Ȃ̂�2, a.m(b, c)�̖߂�l��-1 �ƂȂ�.
+ *
+ * ��2: d = a.f;
+ * ��2�̎��s���ɂ�����, a�̓t�B�[���h�̃R���e�i�Ȃ̂�0, b�̓t�B�[���h�Ȃ̂�1 �ƂȂ�. + * + */ + private int occurrenceExp; + public static final int OCCURRENCE_EXP_CONTAINER = 0; + public static final int OCCURRENCE_EXP_RECEIVER = 0; + public static final int OCCURRENCE_EXP_FIELD = 1; + public static final int OCCURRENCE_EXP_ARRAY = 1; + public static final int OCCURRENCE_EXP_FIRST_ARG = 1; + public static final int OCCURRENCE_EXP_RETURN = -1; + + public Alias(String objectId, TracePoint occurrencePoint, int occurrenceExp) { + this.objectId = objectId; + this.occurrencePoint = occurrencePoint; + this.occurrenceExp = occurrenceExp; + } + + public String getObjectId() { + return objectId; + } + + public TracePoint getOccurrencePoint() { + return occurrencePoint; + } + + public int getOccurrenceExp() { + return occurrenceExp; + } + + public MethodExecution getMethodExecution() { + return occurrencePoint.getMethodExecution(); + } + + public String getMethodExecutionClassName() { + MethodExecution methodExecution = occurrencePoint.getMethodExecution(); + return Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()); + } + + public String getMethodSignature() { + return occurrencePoint.getMethodExecution().getCallerSideSignature(); + } + + public int getLineNo() { + Statement statement = occurrencePoint.getStatement(); + return statement.getLineNo(); + } + + public String getStatementType() { + Statement statement = occurrencePoint.getStatement(); + String statementType = ""; + if (statement instanceof FieldAccess) { + FieldAccess fa = (FieldAccess)statement; + statementType = "FieldAccess"; + } else if (statement instanceof FieldUpdate) { + FieldUpdate fu = (FieldUpdate)statement; + statementType = "FieldUpdate"; + } else if (statement instanceof ArrayAccess) { + ArrayAccess aa = (ArrayAccess)statement; + statementType = "ArrayAccess"; + } else if (statement instanceof ArrayUpdate) { + ArrayUpdate au = (ArrayUpdate)statement; + statementType = "ArrayUpdate"; + } else if (statement instanceof ArrayCreate) { + ArrayCreate ac = (ArrayCreate)statement; + statementType = "ArrayCreate"; + } else if (statement instanceof MethodInvocation) { + MethodExecution me = ((MethodInvocation)statement).getCalledMethodExecution(); + statementType = "MethodInvocation"; + } + return statementType; + } + + public String getStatementSignature() { + Statement statement = occurrencePoint.getStatement(); + String statementSignature = ""; + if (statement instanceof FieldAccess) { + FieldAccess fa = (FieldAccess)statement; + statementSignature = fa.getFieldName(); + } else if (statement instanceof FieldUpdate) { + FieldUpdate fu = (FieldUpdate)statement; + statementSignature = fu.getFieldName(); + } else if (statement instanceof ArrayAccess) { + ArrayAccess aa = (ArrayAccess)statement; + statementSignature = aa.getArrayClassName() + "[" + aa.getIndex() + "]"; + } else if (statement instanceof ArrayUpdate) { + ArrayUpdate au = (ArrayUpdate)statement; + statementSignature = au.getArrayClassName() + "[" + au.getIndex() + "]"; + } else if (statement instanceof ArrayCreate) { + ArrayCreate ac = (ArrayCreate)statement; + statementSignature = ac.getArrayClassName(); + } else if (statement instanceof MethodInvocation) { + MethodExecution me = ((MethodInvocation)statement).getCalledMethodExecution(); + statementSignature = me.getCallerSideSignature(); + } + return statementSignature; + } + + public String getClassName() { + Statement statement = occurrencePoint.getStatement(); + String className = ""; + if (statement instanceof FieldAccess) { + if (occurrenceExp == OCCURRENCE_EXP_CONTAINER) { + className = ((FieldAccess) statement).getContainerClassName(); + } else if (occurrenceExp == OCCURRENCE_EXP_FIELD) { + className = ((FieldAccess) statement).getValueClassName(); + } + } else if (statement instanceof FieldUpdate) { + if (occurrenceExp == OCCURRENCE_EXP_CONTAINER) { + className = ((FieldUpdate) statement).getContainerClassName(); + } else if (occurrenceExp == OCCURRENCE_EXP_FIELD) { + className = ((FieldUpdate) statement).getValueClassName(); + } + } else if (statement instanceof ArrayAccess) { + className = ((ArrayAccess) statement).getValueClassName(); + } else if (statement instanceof ArrayUpdate) { + className = ((ArrayUpdate) statement).getValueClassName(); + } else if (statement instanceof ArrayCreate) { + className = ((ArrayCreate) statement).getArrayClassName(); + } else if (statement instanceof MethodInvocation) { + MethodExecution me = ((MethodInvocation)statement).getCalledMethodExecution(); + if (occurrenceExp == OCCURRENCE_EXP_RETURN) { + className = me.getReturnValue().getActualType(); + } else if (occurrenceExp == OCCURRENCE_EXP_RECEIVER) { + className = me.getThisClassName(); + } else { + int index = occurrenceExp - OCCURRENCE_EXP_FIRST_ARG; + ArrayList args = me.getArguments(); + if (index >= 0 && index < args.size()) { + className = me.getArguments().get(index).getActualType(); + } + } + } + return className; + } + + public String getOccurrenceText() { + String statementType = getStatementType(); + switch (statementType) { + case "FieldAccess": + case "FieldUpdate": + return (occurrenceExp == 0) ? "container" : "field"; + case "ArrayAccess": + case "ArrayUpdate": + return (occurrenceExp == 0) ? "arrayObject" : "arrayValue"; + case "ArrayCreate": + return "return"; + case "MethodInvocation": + if (occurrenceExp <= 0) { + return (occurrenceExp == 0) ? "receiver" : "return"; + } + final String[] ORDER_TEXT = {"th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th"}; // 0-13�ɑΉ� + final String ARG = " arg"; + if (occurrenceExp % 100 >= ORDER_TEXT.length) { + return occurrenceExp + ORDER_TEXT[occurrenceExp % 10] + ARG; // ��2����14�ȏ�Ȃ�, ��1���̐����ɑΉ������� + } else if (occurrenceExp % 100 >= 0) { + return occurrenceExp + ORDER_TEXT[occurrenceExp % 100] + ARG; // ��2����0�ȏ�13�ȉ��Ȃ�, ��2���̐����ɑΉ������� + } + } + return String.valueOf(occurrenceExp); + } + +// @Override +// public String toString() { +// Statement statement = occurrencePoint.getStatement(); +// String className = getClassName(); +// String methodSignature = getMethodSignature(); +// String statementType = getStatementType(); +// String statementSigunarure = getStatementSignature(); +// String indent = " "; +// StringBuilder str = new StringBuilder(); +// str.append("objId: " + objectId + " (class = " + className + ")" + "\n"); +// str.append("tp: " + occurrencePoint + "\n"); +// str.append(indent + "signature: " + methodSignature + "\n"); +// str.append(indent + "lineNo: " + statement.getLineNo() + "\n"); +// str.append(indent + "statementType: " + statementType + " -> " + statementSigunarure + "\n"); +// str.append("occurrenceExp: " + occurrenceExp + "\n"); +// return str.toString(); +// } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/CallStackLabelProvider.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/CallStackLabelProvider.java new file mode 100644 index 0000000..f6d1c89 --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/CallStackLabelProvider.java @@ -0,0 +1,47 @@ +package org.ntlab.reverseDebugger; + +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreeNode; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; +import org.ntlab.debuggingControl.MethodCaller; + +import com.sun.jdi.ClassNotLoadedException; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.InvalidTypeException; +import com.sun.jdi.InvocationException; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.StringReference; +import com.sun.jdi.ThreadReference; + +public class CallStackLabelProvider extends LabelProvider { + + @Override + public String getText(Object element) { + if (element instanceof TreeNode) { + Object value = ((TreeNode)element).getValue(); + if (value instanceof MethodCaller) { + MethodCaller mc = (MethodCaller)value; + return "ThreadID: " + mc.getThreadId(); + } + if (value instanceof CallStackModel) { + CallStackModel callStackModel = (CallStackModel)value; + StringBuilder text = new StringBuilder(); + text.append(callStackModel.getSignature()); + text.append(" line: "); + text.append(callStackModel.getCallLineNo()); + return text.toString(); + } + } + return ""; + } + + @Override + public Image getImage(Object element) { + if (element instanceof TreeNode) { + return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT); + } + return null; + } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/CallStackModel.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/CallStackModel.java new file mode 100644 index 0000000..f8428f6 --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/CallStackModel.java @@ -0,0 +1,56 @@ +package org.ntlab.reverseDebugger; + +import org.ntlab.debuggingControl.MethodCaller; + +import com.sun.jdi.ClassNotLoadedException; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.IntegerValue; +import com.sun.jdi.InvalidTypeException; +import com.sun.jdi.InvocationException; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.StringReference; +import com.sun.jdi.ThreadReference; +import com.sun.jdi.Value; +import com.sun.jdi.VirtualMachine; + +public class CallStackModel { + private MethodCaller methodExecutionMc; + private int callLineNo; + + public CallStackModel(VirtualMachine vm, ThreadReference thread, ObjectReference methodExecution, int callLineNo) { + methodExecutionMc = new MethodCaller(vm, thread, methodExecution); + this.callLineNo = callLineNo; + } + + public VirtualMachine getVm() { + return methodExecutionMc.getVm(); + } + + public ThreadReference getThread() { + return methodExecutionMc.getThread(); + } + + public MethodCaller getMethodCaller() { + return methodExecutionMc; + } + + public int getCallLineNo() { + return callLineNo; + } + + public String getSignature() { + String signature = ""; + try { + signature = ((StringReference)methodExecutionMc.callInstanceMethod("getSignature")).value(); + } catch (InvalidTypeException | ClassNotLoadedException + | InvocationException | IncompatibleThreadStateException e) { + e.printStackTrace(); + } + return signature; + } + + public Value callInstanceMethod(String methodName, Value... args) + throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { + return methodExecutionMc.callInstanceMethod(methodName, args); + } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/CallStackModels.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/CallStackModels.java new file mode 100644 index 0000000..b9c52d4 --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/CallStackModels.java @@ -0,0 +1,97 @@ +package org.ntlab.reverseDebugger; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.TreeNode; +import org.ntlab.debuggingControl.MethodCaller; + +import com.sun.jdi.ClassNotLoadedException; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.IntegerValue; +import com.sun.jdi.InvalidTypeException; +import com.sun.jdi.InvocationException; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.ThreadReference; +import com.sun.jdi.Value; +import com.sun.jdi.VirtualMachine; +import com.sun.jdi.event.MethodEntryEvent; + +public class CallStackModels { + private List callStackModels = new ArrayList<>(); + + public List getCallStackModels() { + return callStackModels; + } + + public TreeNode[] getCallStackModelsTreeNodes() { + TreeNode[] roots = new TreeNode[1]; + if (callStackModels.isEmpty()) { + return roots; + } + CallStackModel callStackModel = callStackModels.get(0); + roots[0] = new TreeNode(new MethodCaller(callStackModel.getVm(), callStackModel.getThread())); + TreeNode parentNode = roots[0]; + TreeNode[] childrenNode = new TreeNode[callStackModels.size()]; + parentNode.setChildren(childrenNode); + for (int i = 0; i < callStackModels.size(); i++) { + TreeNode childNode = new TreeNode(callStackModels.get(i)); + childNode.setParent(parentNode); + childrenNode[i] = childNode; + } + return roots; + } + + public void reset() { + callStackModels.clear(); + } + + public void updateByDebuggerStopMethodExecution(MethodCaller me) { + if (me == null) { + return; + } + try { + VirtualMachine vm = me.getVm(); + ThreadReference thread = me.getThread(); + int lineNo = thread.frame(0).location().lineNumber(); + update(vm, thread, me.getObj(), lineNo); + } catch (InvalidTypeException | ClassNotLoadedException + | InvocationException | IncompatibleThreadStateException e) { + e.printStackTrace(); + } + } + + public void updateByAlias(MethodCaller alias) { + if (alias == null) { + return; + } + VirtualMachine vm = alias.getVm(); + ThreadReference thread = alias.getThread(); + try { + ObjectReference me = (ObjectReference)alias.callInstanceMethod("getMethodExecution"); + int lineNo = ((IntegerValue)alias.callInstanceMethod("getLineNo")).value(); + update(vm, thread, me, lineNo); + } catch (InvalidTypeException | ClassNotLoadedException + | InvocationException | IncompatibleThreadStateException e) { + e.printStackTrace(); + } + } + + private void update(VirtualMachine vm, ThreadReference thread, ObjectReference me, int topMethodCallLineNo) + throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { + callStackModels.clear(); + ObjectReference childMe = null; + int callLineNo = topMethodCallLineNo; + while (me != null) { + CallStackModel callStackModel = new CallStackModel(vm, thread, me, callLineNo); + callStackModels.add(callStackModel); + childMe = me; + me = (ObjectReference)callStackModel.callInstanceMethod("getParent"); + if (me != null) { + MethodCaller mc = new MethodCaller(vm, thread, me); + ObjectReference callStatement = (ObjectReference)mc.callInstanceMethod("getMethodInvocation", childMe); + callLineNo = ((IntegerValue)mc.setObj(callStatement).callInstanceMethod("getLineNo")).value(); + } + } + } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/CallStackView.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/CallStackView.java new file mode 100644 index 0000000..2030df7 --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/CallStackView.java @@ -0,0 +1,111 @@ +package org.ntlab.reverseDebugger; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TreeNode; +import org.eclipse.jface.viewers.TreeNodeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.ViewPart; +import org.ntlab.debuggingControl.MethodCaller; + +public class CallStackView extends ViewPart { + private static TreeViewer viewer; + private IAction refreshAction; + private static CallStackModels callStackModels = new CallStackModels(); + private JavaEditorOperator javaEditorOperator = new JavaEditorOperator(); + public static final String ID = "org.ntlab.reverseDebugger.callStackView"; + + public CallStackView() { + // TODO Auto-generated constructor stub + System.out.println("callStackView�N���X���������ꂽ��"); + } + + @Override + public void createPartControl(Composite parent) { + // TODO Auto-generated method stub + System.out.println("CallStackView#createPartControl(Composite)���Ă΂ꂽ��!"); + viewer = new TreeViewer(parent); + viewer.setContentProvider(new TreeNodeContentProvider()); + viewer.setLabelProvider(new CallStackLabelProvider()); + viewer.expandAll(); + + // �I�������J�����ɑΉ����郁�\�b�h���s�̃\�[�X�t�@�C�����J�����郊�X�i�[��o�^���� + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + IStructuredSelection sel = (IStructuredSelection)event.getSelection(); + Object element = sel.getFirstElement(); + if (element instanceof TreeNode) { + Object value = ((TreeNode)element).getValue(); + if (value instanceof CallStackModel) { + MethodCaller methodExecution = ((CallStackModel)value).getMethodCaller(); + SeedAliasView.createSeedAliasesByMethodExecution(methodExecution); + SeedAliasView.refresh(); + javaEditorOperator.openSrcFileOfMethodExecution(methodExecution); + } + } + } + }); + createActions(); + createToolBar(); + createMenuBar(); + } + + @Override + public void setFocus() { + // TODO Auto-generated method stub + viewer.getControl().setFocus(); + } + + private void createActions() { + refreshAction = new Action() { + @Override + public void run() { + refresh(); + } + }; + refreshAction.setText("refresh"); + refreshAction.setToolTipText("refresh"); + refreshAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ELCL_SYNCED)); + } + + private void createToolBar() { + IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager(); + mgr.add(refreshAction); + } + + private void createMenuBar() { + IMenuManager mgr = getViewSite().getActionBars().getMenuManager(); + mgr.add(refreshAction); + } + + public static void updateByAlias(MethodCaller alias) { + callStackModels.updateByAlias(alias); + } + + public static void refresh() { + if (callStackModels.getCallStackModels().isEmpty()) { + MethodCaller currentMe = SeedAliasView.getDebuggerStopMethodExecution(); + callStackModels.updateByDebuggerStopMethodExecution(currentMe); + } + TreeNode[] nodes = callStackModels.getCallStackModelsTreeNodes(); + if (nodes == null || nodes[0] == null) { + return; + } + viewer.setInput(nodes); + viewer.expandAll(); + } + + public static void reset() { + callStackModels.reset(); + refresh(); + } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/JavaEditorOperator.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/JavaEditorOperator.java new file mode 100644 index 0000000..d332493 --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/JavaEditorOperator.java @@ -0,0 +1,219 @@ +package org.ntlab.reverseDebugger; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.Signature; +import org.eclipse.jdt.ui.JavaUI; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.PartInitException; +import org.ntlab.debuggingControl.MethodCaller; + +import com.sun.jdi.ClassNotLoadedException; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.InvalidTypeException; +import com.sun.jdi.InvocationException; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.StringReference; +import com.sun.jdi.ThreadReference; +import com.sun.jdi.Value; +import com.sun.jdi.VirtualMachine; + +public class JavaEditorOperator { + private static final String TRACE = "org.ntlab.traceCollector.tracer.trace"; + + public void openSrcFileOfAlias(MethodCaller alias) { + try { + ObjectReference methodExecution = (ObjectReference)alias.callInstanceMethod("getMethodExecution"); + MethodCaller meCaller = new MethodCaller(alias.getVm(), alias.getThread(), methodExecution); + openSrcFileOfMethodExecution(meCaller); + } catch (InvalidTypeException | ClassNotLoadedException + | InvocationException | IncompatibleThreadStateException e) { + e.printStackTrace(); + } + } + + /** + * �����œn����meCaller���ɂ���methodExecution����`����Ă���N���X�̃\�[�X�R�[�h��Ώ�Eclipse�̃G�f�B�^�ŊJ������ + * + * @param meCaller + */ + public void openSrcFileOfMethodExecution(MethodCaller meCaller) { + try { + IType type = findIType(meCaller); + if (type != null) { + IMethod method = findIMethod(meCaller, type); + if (method != null) { + openSrcFileOfIMethod(type, method); + } + } + } catch (InvalidTypeException | ClassNotLoadedException + | InvocationException | IncompatibleThreadStateException e) { + e.printStackTrace(); + } + } + + /** + * �����œn����IType��IMethod�ɑΉ�����\�[�X�R�[�h��Ώ�Eclipse�̃G�f�B�^�ŊJ������ + * + * @param type + * @param method + */ + private void openSrcFileOfIMethod(IType type, IMethod method) throws InvalidTypeException, ClassNotLoadedException, + InvocationException, IncompatibleThreadStateException { + openInJavaEditor(type, method); + } + + private IType findIType(MethodCaller meCaller) throws InvalidTypeException, + ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { + StringReference declaringClassName = (StringReference)meCaller.callInstanceMethod("getDeclaringClassName"); + String projectPath = getLoaderPath(meCaller, declaringClassName); + IType type = null; + if (projectPath != null) { + IJavaProject javaProject = findJavaProject(projectPath); + if (javaProject != null) { + StringReference methodSignature = (StringReference)meCaller.callInstanceMethod("getSignature"); + try { + type = javaProject.findType(declaringClassName.value()); + } catch (JavaModelException e) { + e.printStackTrace(); + } + } + } + return type; + } + + private String getLoaderPath(MethodCaller meCaller, StringReference declaringClassName) + throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { + ObjectReference classInfo = (ObjectReference)meCaller.callStaticMethod(TRACE, "TraceJSON", "getClassInfo", declaringClassName); + if (classInfo == null) { + declaringClassName = (StringReference)meCaller.callInstanceMethod("getThisClassName"); + classInfo = (ObjectReference)meCaller.callStaticMethod(TRACE, "TraceJSON", "getClassInfo", declaringClassName); + } + String loaderPath = null; + if (classInfo != null) { + // �Ȃ���loaderPath���擾�ł��Ă��Ȃ����߁A���ۂɏo�͂����JSON�g���[�X���Q�l�ɂ���path����^���Ă݂� + MethodCaller classInfoMethodCaller = new MethodCaller(meCaller.getVm(), meCaller.getThread(), classInfo); + String path = ((StringReference)classInfoMethodCaller.callInstanceMethod("getPath")).value(); + String declaringClassNameString = declaringClassName.value().replace(".", "/"); + loaderPath = path.substring(0, path.indexOf(declaringClassNameString)); // path����N���X�̊��S���薼�ȍ~��S�ĊO�������̂�projectPath�ɂ��Ă݂� + } + return loaderPath; + } + + private IJavaProject findJavaProject(String projectPath) { + IJavaProject javaProject = null; + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IProject[] projects = root.getProjects(); + for (IProject project : projects) { + if (checkProjectPath(project, projectPath)) { + javaProject = JavaCore.create(project); + break; + } + } + return javaProject; + } + + private boolean checkProjectPath(IProject project, String projectPath) { + String projectLocation = project.getLocation().toString(); + if (projectPath.startsWith(projectLocation)) { + String[] projectPathSplit = projectPath.split(projectLocation); + return (projectPathSplit[1].charAt(0) == '/'); // �v���W�F�N�g���̑O����v�ɂ�鑼�v���W�F�N�g�Ƃ̌딻�������� + } + return false; + } + + private void openInJavaEditor(IType type, IMethod method) { + try { + if (type != null && method != null) { + IEditorPart editor = JavaUI.openInEditor(type); + if (!type.isLocal() && !type.isMember()) { + JavaUI.revealInEditor(editor, (IJavaElement) method); + } + } + } catch (PartInitException | JavaModelException e) { + e.printStackTrace(); + } + } + + private IMethod findIMethod(MethodCaller meCaller, IType type) throws InvalidTypeException, + ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { + IMethod method = null; + if (type != null) { + StringReference methodSignature = (StringReference)meCaller.callInstanceMethod("getSignature"); + method = findIMethod(type, methodSignature.value()); + } + return method; + } + + private IMethod findIMethod(IType type, String methodSignature) { + try { + for (IMethod method : type.getMethods()) { + if (checkMethodSignature(type, method, methodSignature)) { + return method; + } + } + } catch (JavaModelException e) { + e.printStackTrace(); + } + return null; + } + + private boolean checkMethodSignature(IType type, IMethod method, String methodSignature) { + String fqcn = type.getFullyQualifiedName(); + try { + StringBuilder jdtMethodSignature = new StringBuilder(); + jdtMethodSignature.append((method.isConstructor()) ? (fqcn + "(") : (fqcn + "." + method.getElementName() + "(")); + if (methodSignature.contains(jdtMethodSignature)) { + // ������v���Ă����ꍇ�Ɍ���A�������X�g����������ł���v���邩�ǂ����𔻒� (�I�[�o�[���[�h�ɂ��딻��������) + jdtMethodSignature.append(String.join(",", parseFQCNParameters(type, method)) + ")"); // �S�����̃V�O�l�`�������S����N���X���ɕϊ�����,�ŋ�؂��������� + return methodSignature.contains(jdtMethodSignature); + } + } catch (JavaModelException e) { + e.printStackTrace(); + } + return false; + } + + /** + * IMethod����擾�ł���S�����̃V�O�l�`�������S����N���X���ɒu�������Ċi�[�������X�g��Ԃ� + * + * @param type + * @param method + * @return + */ + private List parseFQCNParameters(IType type, IMethod method) throws JavaModelException { + List parameters = new ArrayList<>(); + for (String parameterType : method.getParameterTypes()) { + String readableType = Signature.toString(parameterType); // �V�O�l�`���̕�������^���̕�����ɕϊ� (�z��͌���[]���‚�) + String[] readableTypeSplit = { "", "" }; // �^����[]�̕����p + int firstBracketIndex = readableType.indexOf("[]"); + final int NO_BRACKET_INDEX = -1; + if (firstBracketIndex == NO_BRACKET_INDEX) { + readableTypeSplit[0] = readableType; // �^�� + } else { + readableTypeSplit[0] = readableType.substring(0, firstBracketIndex); // �^�� + readableTypeSplit[1] = readableType.substring(firstBracketIndex); // �^���̌���[]�S�� + } + String[][] resolveType = type.resolveType(readableTypeSplit[0]); // �p�b�P�[�W���ƃN���X���̑g�ݍ��킹���擾 + if (resolveType != null) { + if (resolveType[0][0].isEmpty()) { + readableTypeSplit[0] = (resolveType[0][1]); // �f�t�H���g�p�b�P�[�W�̏ꍇ�̓p�b�P�[�W����.�͓���Ȃ� + } else { + readableTypeSplit[0] = (resolveType[0][0] + "." + resolveType[0][1]); // ���S����N���X�� + } + } + parameters.add(readableTypeSplit[0] + readableTypeSplit[1]); + } + return parameters; + } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliasLabelProvider.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliasLabelProvider.java new file mode 100644 index 0000000..0ae2cf7 --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliasLabelProvider.java @@ -0,0 +1,61 @@ +package org.ntlab.reverseDebugger; + +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; +import org.ntlab.debuggingControl.MethodCaller; + +import com.sun.jdi.ClassNotLoadedException; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.IntegerValue; +import com.sun.jdi.InvalidTypeException; +import com.sun.jdi.InvocationException; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.StringReference; + +public class ObjectFlowAliasLabelProvider extends LabelProvider implements ITableLabelProvider { + + @Override + public String getColumnText(Object element, int columnIndex) { + if (element instanceof MethodCaller) { + MethodCaller mc = (MethodCaller)element; + if (mc.getObj() == null) { + return ""; + } + try { + switch (columnIndex) { + case 0: + return ((StringReference)mc.callInstanceMethod("getObjectId")).value(); + case 1: + return ((StringReference)mc.callInstanceMethod("getClassName")).value(); + case 2: + return ((StringReference)mc.callInstanceMethod("getMethodExecutionClassName")).value(); + case 3: + return String.valueOf(((IntegerValue)mc.callInstanceMethod("getLineNo")).value()); + case 4: + return ((StringReference)mc.callInstanceMethod("getStatementType")).value(); + case 5: + return ((StringReference)mc.callInstanceMethod("getStatementSignature")).value(); + case 6: + return ((StringReference)mc.callInstanceMethod("getOccurrenceText")).value(); + } + } catch (InvalidTypeException | ClassNotLoadedException + | InvocationException | IncompatibleThreadStateException e) { + e.printStackTrace(); + } + } + return "�e�X�g�p�e�L�X�g" + columnIndex; + } + + @Override + public Image getColumnImage(Object element, int columnIndex) { + return getImage(element); + } + + @Override + public Image getImage(Object element) { + return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT); + } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliasView.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliasView.java new file mode 100644 index 0000000..bacc21d --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliasView.java @@ -0,0 +1,173 @@ +package org.ntlab.reverseDebugger; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.ViewPart; +import org.ntlab.debuggingControl.MethodCaller; + +public class ObjectFlowAliasView extends ViewPart { + private static TableViewer viewer; + private IAction refreshAction; + private IAction findSeedAliasesAction; + private MethodCaller selectObjectFlowAlias; + private static ObjectFlowAliases objectFlowAliases = new ObjectFlowAliases(); + private JavaEditorOperator javaEditorOperator = new JavaEditorOperator(); + public static final String ID = "org.ntlab.reverseDebugger.objectFlowAliasView"; + + public ObjectFlowAliasView() { + // TODO Auto-generated constructor stub + System.out.println("ObjectFlowView�N���X���������ꂽ��!"); + } + + @Override + public void createPartControl(Composite parent) { + // TODO Auto-generated method stub + System.out.println("ObjectFlowView#createPartControl(Composite)���Ă΂ꂽ��!"); + viewer = new TableViewer(parent, SWT.FULL_SELECTION); + Table table = viewer.getTable(); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + // �e�[�u���̃J�������쐬 + String[] tableColumnTexts = {"objectID", "objectType", "srcFile", "lineNo", "statementType", "statementSignature", "occurrence"}; + int[] tableColumnWidth = {150, 160, 160, 80, 180, 300, 110}; + TableColumn[] tableColumns = new TableColumn[tableColumnTexts.length]; + for (int i = 0; i < tableColumns.length; i++) { + tableColumns[i] = new TableColumn(table, SWT.NULL); + tableColumns[i].setText(tableColumnTexts[i]); + tableColumns[i].setWidth(tableColumnWidth[i]); + } + viewer.setContentProvider(new ArrayContentProvider()); + viewer.setLabelProvider(new ObjectFlowAliasLabelProvider()); + viewer.setInput(objectFlowAliases.getObjectFlowSingleList(true)); + + // �I�������J�����ɑΉ�����G�C���A�X������郁�\�b�h���s���̑S�ẴV�[�h�G�C���A�X�̈ꗗ�𐶐����郊�X�i�[��o�^ +// viewer.addSelectionChangedListener(new ISelectionChangedListener() { +// @Override +// public void selectionChanged(SelectionChangedEvent event) { +// IStructuredSelection sel = (IStructuredSelection)event.getSelection(); +// Object element = sel.getFirstElement(); +// if (element instanceof MethodCaller) { +// MethodCaller alias = (MethodCaller)element; +// SeedAliasView.createSeedAliases(alias); +// SeedAliasView.refresh(); +// CallStackView.updateByAlias(alias); +// CallStackView.refresh(); +// javaEditorOperator.openSrcFileOfAlias(alias); +// } +// } +// }); + + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + IStructuredSelection sel = (IStructuredSelection)event.getSelection(); + Object element = sel.getFirstElement(); + if (element instanceof MethodCaller) { + selectObjectFlowAlias = (MethodCaller)element; + javaEditorOperator.openSrcFileOfAlias(selectObjectFlowAlias); + } + } + }); + + createActions(); + createToolBar(); + createMenuBar(); + createPopupMenu(); + } + + @Override + public void setFocus() { + // TODO Auto-generated method stub + viewer.getControl().setFocus(); + } + + private void createActions() { + refreshAction = new Action() { + @Override + public void run() { + refresh(); + } + }; + refreshAction.setText("refresh"); + refreshAction.setToolTipText("refresh"); + refreshAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ELCL_SYNCED)); + + findSeedAliasesAction = new Action() { + @Override + public void run() { + findSeedAliases(); + } + }; + findSeedAliasesAction.setText("findSeedAliases"); + findSeedAliasesAction.setToolTipText("findSeedAliases"); + findSeedAliasesAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_TASK_TSK)); + } + + private void createToolBar() { + IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager(); + mgr.add(refreshAction); + } + + private void createMenuBar() { + IMenuManager mgr = getViewSite().getActionBars().getMenuManager(); + mgr.add(refreshAction); + } + + private void createPopupMenu() { + MenuManager menuMgr = new MenuManager("#PopupMenu"); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + @Override + public void menuAboutToShow(IMenuManager manager) { + manager.add(findSeedAliasesAction); + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + }); + Menu menu = menuMgr.createContextMenu(viewer.getControl()); + viewer.getControl().setMenu(menu); + getSite().registerContextMenu(menuMgr, viewer); + } + + public static void createObjectFlow(MethodCaller seedAlias) { + objectFlowAliases.createObjectFlow(seedAlias); + } + + private void findSeedAliases() { + SeedAliasView.createSeedAliasesByAlias(selectObjectFlowAlias); + SeedAliasView.refresh(); + CallStackView.updateByAlias(selectObjectFlowAlias); + CallStackView.refresh(); + javaEditorOperator.openSrcFileOfAlias(selectObjectFlowAlias); + } + + public static void refresh() { + viewer.setInput(objectFlowAliases.getObjectFlowSingleList(true)); + } + + public static void reset() { + objectFlowAliases.reset(); + viewer.setInput(objectFlowAliases.getObjectFlowSingleList(true)); + } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliases.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliases.java new file mode 100644 index 0000000..df84f3c --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliases.java @@ -0,0 +1,77 @@ +package org.ntlab.reverseDebugger; + +import java.util.ArrayList; +import java.util.List; + +import org.ntlab.debuggingControl.MethodCaller; + +import com.sun.jdi.ClassNotLoadedException; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.IntegerValue; +import com.sun.jdi.InvalidTypeException; +import com.sun.jdi.InvocationException; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.Value; +import com.sun.jdi.VirtualMachine; + +public class ObjectFlowAliases { + private List> objectFlowAliases = new ArrayList<>(); + private static final String TRACE = "org.ntlab.traceCollector.tracer.trace"; + private static final String ANALYZER = "org.ntlab.reverseDebugger"; + + public void reset() { + objectFlowAliases.clear(); + } + + public List> getObjectFlow() { + return objectFlowAliases; + } + + public List> getObjectFlow(MethodCaller seedAlias) { + createObjectFlow(seedAlias); + return objectFlowAliases; + } + + public List getObjectFlowSingleList(boolean hasBound) { + List list = new ArrayList<>(); + for (int i = 0; i < objectFlowAliases.size(); i++) { + for (int j = 0; j < objectFlowAliases.get(i).size(); j++) { + list.add(objectFlowAliases.get(i).get(j)); + } + if (hasBound) { + list.add(new MethodCaller(null, null)); // ���E�p�̃_�~�[�C���X�^���X�𐶐����Ēlj� + } + } + return list; + } + + public List getObjectFlowSingleList(MethodCaller seedAlias, boolean hasBound) { + createObjectFlow(seedAlias); + return getObjectFlowSingleList(hasBound); + } + + public void createObjectFlow(MethodCaller seedAlias) { + MethodCaller mc = new MethodCaller(seedAlias.getVm(), seedAlias.getThread()); + objectFlowAliases.clear(); + try { + // �I�������G�C���A�X���N�_�ɃI�u�W�F�N�g�t���[���Ăяo���Č��ʂ����X�g�Ŏ󂯎�� +// ObjectReference aliasListsReference = (ObjectReference)seedAlias.callStaticMethod(TRACE, "TraceJSON", "getObjectFlow", seedAlias.getObj()); + ObjectReference aliasListsReference = (ObjectReference)seedAlias.callStaticMethod(ANALYZER, "OnlineTraceAnalyzer", "getObjectFlow", seedAlias.getObj()); + + // �擾�������X�g�̒��g�����[�v�ʼn񂵂Ȃ�����o��, �Ǘ��p�̃��X�g�ɋl�ߒ��� + int aliasListsSize = ((IntegerValue)mc.setObj(aliasListsReference).callInstanceMethod("size")).value(); + for (int i = 0; i < aliasListsSize; i++) { + List list = new ArrayList<>(); + objectFlowAliases.add(list); + ObjectReference aliasListReference = (ObjectReference)mc.setObj(aliasListsReference).callInstanceMethod("get", mc.getVm().mirrorOf(i)); + int aliasListSize = ((IntegerValue)mc.setObj(aliasListReference).callInstanceMethod("size")).value(); + for (int j = 0; j < aliasListSize; j++) { + ObjectReference aliasReference = (ObjectReference)mc.setObj(aliasListReference).callInstanceMethod("get", mc.getVm().mirrorOf(j)); + list.add(new MethodCaller(seedAlias.getVm(), seedAlias.getThread(), aliasReference)); + } + } + } catch (InvalidTypeException | ClassNotLoadedException | InvocationException | IncompatibleThreadStateException e) { + e.printStackTrace(); + } + } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/OnlineTraceAnalyzer.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/OnlineTraceAnalyzer.java new file mode 100644 index 0000000..935ab76 --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/OnlineTraceAnalyzer.java @@ -0,0 +1,238 @@ +package org.ntlab.reverseDebugger; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +// import org.ntlab.traceCollector.tracer.trace.Alias; +import org.ntlab.traceCollector.tracer.trace.ArrayAccess; +import org.ntlab.traceCollector.tracer.trace.ArrayCreate; +import org.ntlab.traceCollector.tracer.trace.ArrayUpdate; +import org.ntlab.traceCollector.tracer.trace.FieldAccess; +import org.ntlab.traceCollector.tracer.trace.FieldUpdate; +import org.ntlab.traceCollector.tracer.trace.MethodExecution; +import org.ntlab.traceCollector.tracer.trace.MethodInvocation; +import org.ntlab.traceCollector.tracer.trace.ObjectReference; +import org.ntlab.traceCollector.tracer.trace.Statement; +import org.ntlab.traceCollector.tracer.trace.TraceJSON; +import org.ntlab.traceCollector.tracer.trace.TracePoint; + +public class OnlineTraceAnalyzer { + + public void test2() { + System.out.println("OnlineTraceAnalyzer#test2()���Ă΂ꂽ��!"); + TraceJSON.test(); + System.out.println("OnlineTraceAnalyzer#test2()���甲�����!"); + } + + public static ArrayList findAllStartAlias(MethodExecution me) { + System.out.println("OnlineTraceAnalyzer#findAllStartAlias(MethodExecution)���Ă΂ꂽ��!"); + ArrayList startAliasList = new ArrayList<>(); + List statements = me.getStatements(); + String[] primitives = {"byte", "short", "int", "long", "float", "double", "char", "boolean"}; + List primitiveList = Arrays.asList(primitives); + for (int i = 0; i < statements.size(); i++) { + TracePoint tp = me.getTracePoint(i); + Statement statement = statements.get(i); + if (statement instanceof FieldAccess) { + FieldAccess fa = (FieldAccess)statement; + String objId = fa.getContainerObjId(); + if (objId != null && !(objId.equals("0")) && !(primitiveList.contains(fa.getContainerClassName()))) { + startAliasList.add(new Alias(objId, tp, Alias.OCCURRENCE_EXP_CONTAINER)); + } + objId = fa.getValueObjId(); + if (objId != null && !(objId.equals("0")) && !(primitiveList.contains(fa.getValueClassName()))) { + startAliasList.add(new Alias(objId, tp, Alias.OCCURRENCE_EXP_FIELD)); + } + } else if (statement instanceof FieldUpdate) { + FieldUpdate fu = (FieldUpdate)statement; + String objId = fu.getContainerObjId(); + if (objId != null && !(objId.equals("0")) && !(primitiveList.contains(fu.getContainerClassName()))) { + startAliasList.add(new Alias(objId, tp, Alias.OCCURRENCE_EXP_CONTAINER)); + } + objId = fu.getValueObjId(); + if (objId != null && !(objId.equals("0")) && !(primitiveList.contains(fu.getValueClassName()))) { + startAliasList.add(new Alias(objId, tp, Alias.OCCURRENCE_EXP_FIELD)); + } + } else if (statement instanceof ArrayAccess) { + ArrayAccess aa = (ArrayAccess)statement; + String valueObjId = aa.getValueObjectId(); + if (valueObjId != null && !(valueObjId.equals("0")) && !(primitiveList.contains(aa.getValueClassName()))) { + startAliasList.add(new Alias(valueObjId, tp, Alias.OCCURRENCE_EXP_ARRAY)); + } + } else if (statement instanceof ArrayUpdate) { + ArrayUpdate au = (ArrayUpdate)statement; + String valueObjId = au.getValueObjectId(); + if (valueObjId != null && !(valueObjId.equals("0")) && !(primitiveList.contains(au.getValueClassName()))) { + startAliasList.add(new Alias(valueObjId, tp, Alias.OCCURRENCE_EXP_ARRAY)); + } + } else if (statement instanceof ArrayCreate) { + ArrayCreate ac = (ArrayCreate)statement; + String arrayObjId = ac.getArrayObjectId(); + if (arrayObjId != null && !(arrayObjId.equals("0")) && !(primitiveList.contains(ac.getArrayClassName()))) { + startAliasList.add(new Alias(arrayObjId, tp, Alias.OCCURRENCE_EXP_RETURN)); + } + } else if (statement instanceof MethodInvocation) { + MethodExecution calledMe = ((MethodInvocation)statement).getCalledMethodExecution(); + String thisObjId = calledMe.getThisObjId(); + if (thisObjId != null && !(thisObjId.equals("0"))) { + startAliasList.add(new Alias(thisObjId, tp, Alias.OCCURRENCE_EXP_RECEIVER)); + } + List args = calledMe.getArguments(); + for (int j = 0; j < args.size(); j++) { + ObjectReference arg = args.get(j); + String argValueId = arg.getId(); + if (argValueId != null && !(argValueId.equals("0")) && !(primitiveList.contains(arg.getActualType()))) { + startAliasList.add(new Alias(argValueId, tp, (j + Alias.OCCURRENCE_EXP_FIRST_ARG))); + } + } + ObjectReference returnValue = calledMe.getReturnValue(); + if (returnValue != null) { + String returnValueId = returnValue.getId(); + if (returnValueId != null && !(returnValueId.equals("0") && !(primitiveList.contains(returnValue.getActualType())))) { + startAliasList.add(new Alias(returnValueId, tp, Alias.OCCURRENCE_EXP_RETURN)); + } + } + } + } + for (Alias startAlias : startAliasList) { + System.out.println(startAlias); + } + return startAliasList; + } + + private static TracePoint getRecentlyFieldUpdate(TracePoint tp) { + System.out.println("OnlineTraceAnalyzer#getRecentlyFieldUpdate(TracePoint)���Ă΂ꂽ��!"); + Statement statement = tp.getStatement(); + if (statement instanceof FieldAccess) { + FieldAccess fa = (FieldAccess)statement; + return TraceJSON.getFieldUpdateTracePoint(fa.getContainerObjId(), fa.getFieldName(), tp); + } + return null; + } + + private static TracePoint getRecentlyArrayUpdate(TracePoint tp) { + System.out.println("OnlineTraceAnalyzer#getRecentlyArrayUpdate(TracePoint)���Ă΂ꂽ��!"); + Statement statement = tp.getStatement(); + if (statement instanceof ArrayAccess) { + ArrayAccess aa = (ArrayAccess)statement; + return TraceJSON.getArrayUpdateTracePoint(aa.getArrayObjectId(), aa.getIndex(), tp); + } + return null; + } + + public static ArrayList> getObjectFlow(Alias startAlias) { + System.out.println("OnlineTraceAnalyzer#getObjectFlow(Alias)���Ă΂ꂽ��!"); + ArrayList> aliasLists = new ArrayList<>(); + ArrayList aliasList = new ArrayList<>(); + aliasLists.add(aliasList); +// aliasList.add(alias); + String objId = startAlias.getObjectId(); + TracePoint tp = startAlias.getOccurrencePoint().duplicate(); + ArrayList> resultLists = getObjectFlow(aliasLists, objId, tp, 0); +// for (int i = 0; i < resultLists.size(); i++) { +// ArrayList resultList = resultLists.get(i); +// System.out.println("---------------------------------------------------------"); // �m�F�p +// for (Alias alias : resultList) System.out.println(alias); // �m�F�p +// int lastAliasOccurrenceEXP = resultList.get(resultList.size() - 1).getOccurrenceExp(); +// if (lastAliasOccurrenceEXP != Alias.OCCURRENCE_EXP_RETURN) { +// resultLists.remove(resultList); // �����̃G�C���A�X���z�񐶐���R���X�g���N�^�Ăяo���ł͂Ȃ����X�g���폜���� +// } +// } + for (List resultList : resultLists) { + for (Alias resultAlias : resultList) { + System.out.println(resultAlias); + } + } + return resultLists; + } + + private static ArrayList> getObjectFlow(ArrayList> aliasLists, + String objId, TracePoint tp, int side) { + System.out.println("OnlineTraceAnalyzer#getObjectFlow(ArrayList, String, TracePoint, int)���Ă΂ꂽ��!"); + ArrayList aliasList = aliasLists.get(aliasLists.size() - 1); // ����getObjectFlow���\�b�h���s���Ō��‚������G�C���A�X�����Ă������X�g + do { + Statement statement = tp.getStatement(); + if (statement instanceof FieldAccess) { + // �t�B�[���h�Q�Ƃ̏ꍇ + FieldAccess fa = (FieldAccess)statement; + if (fa.getValueObjId().equals(objId)) { + // ���Y�n�_�ł̃G�C���A�X�����X�g�ɒlj��������, �t�B�[���h�ŏI�X�V�ɔ�ԃp�^�[���Ƃ��̂܂ܑk��p�^�[���Ƃŕ��� + aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_FIELD)); + aliasList = new ArrayList<>(aliasList); // ���X�g���̂��f�B�[�v�R�s�[���Ă���(�t�B�[���h�ŏI�X�V�ɔ�ԍċA�����I�����, ���̂܂ܑk��p�^�[���ŗp����) + TracePoint fieldUpdateTp = getRecentlyFieldUpdate(tp); + aliasLists = getObjectFlow(aliasLists, objId, fieldUpdateTp, 0); + aliasLists.add(aliasList); // �ċA�����ɓ���O�Ƀf�B�[�v�R�s�[���Ă������X�g���Ō���ɒlj� (�ȍ~�̑k��ɂ���Č��‚����G�C���A�X�͂��̃��X�g�ɓ������) + } + } else if (statement instanceof ArrayAccess) { + // �z��v�f�Q�Ƃ̏ꍇ + ArrayAccess aa = (ArrayAccess)statement; + if (aa.getValueObjectId().equals(objId)) { + aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_ARRAY)); + aliasList = new ArrayList<>(aliasList); + TracePoint arrayUpdateTp = getRecentlyArrayUpdate(tp); + aliasLists = getObjectFlow(aliasLists, objId, arrayUpdateTp, 0); + aliasLists.add(aliasList); + } + } else if (statement instanceof ArrayCreate) { + // �z�񐶐��̏ꍇ + ArrayCreate ac = (ArrayCreate)statement; + if (ac.getArrayObjectId().equals(objId)) { + aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_RETURN)); // �z�񐶐��� new �^��[] �̖߂�l + return aliasLists; // �z�񐶐��ӏ��̓G�C���A�X�̋N���Ȃ̂ł���ȑO�ɂ͂����Ȃ��͂� + } + } else if (statement instanceof MethodInvocation) { + // ���\�b�h�Ăяo���̏ꍇ + MethodExecution calledMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution(); + ObjectReference returnValue = calledMethodExecution.getReturnValue(); + if (returnValue.getId().equals(objId)) { + // �߂�l�ɃG�C���A�X�̃I�u�W�F�N�gID����v�����ꍇ + aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_RETURN)); + if (calledMethodExecution.isConstructor()) { + return aliasLists; // �R���X�g���N�^�Ăяo���ӏ��̓G�C���A�X�̋N���Ȃ̂ł���ȑO�ɂ͂����Ȃ��͂� + } + TracePoint exitTp = calledMethodExecution.getExitPoint(); // �Ăяo�����\�b�h���s�̍ŏI�X�e�[�g�����g���w��tp���擾 + aliasLists = getObjectFlow(aliasLists, objId, exitTp, side + 1); // �Ăяo����̃��\�b�h���s�ɐ��� + aliasList = aliasLists.get(aliasLists.size() - 1); + } + } + } while (tp.stepBackOver()); // �Ăяo�����ɖ߂邩����ȏ�H��Ȃ��Ȃ�܂Ń��[�v + if (!tp.isValid()) { + return aliasLists; // ����ȏチ�\�b�h���s��k��Ȃ��ꍇ(main���\�b�h�̂���ɑO�Ȃ�)�͂��̎��_�ŏI�� + } + // --- ���̎��_�� tracePoint�� �Ăяo�������w���Ă��� (���O�܂ők���Ă������\�b�h���s�ɂ‚��Ẵ��\�b�h�Ăяo�����w���Ă���) --- + MethodExecution calledMethodExecution = ((MethodInvocation)tp.getStatement()).getCalledMethodExecution(); + ArrayList args = calledMethodExecution.getArguments(); + for (int i = 0; i < args.size(); i++) { + if (args.get(i).getId().equals(objId)) { + // ���\�b�h�Ăяo���̎������ɃG�C���A�X�̃I�u�W�F�N�gID����v�����ꍇ + aliasList.add(new Alias(objId, tp.duplicate(), (i + Alias.OCCURRENCE_EXP_FIRST_ARG))); + if (side == 0) { + // �T���J�n���\�b�h���s�܂��̓t�B�[���h��z��v�f�̍ŏI�X�V�T���Ŕ�񂾐�̃��\�b�h���s����, �X�^�b�N�g���[�X�ł��ǂ��S���\�b�h���s�̏ꍇ + TracePoint previousTp = tp.duplicate(); + previousTp.stepBackOver(); + aliasLists = getObjectFlow(aliasLists, objId, previousTp, 0); // �Ăяo�����̃��\�b�h���s�ɖ߂� + } + } + } + return aliasLists; + } + + public static int countMethodExecutionInTraceCollector(List methodExecutions, String targetSignature, int count, String indent) { + System.out.println("OnlineTraceAnalyzer#countMethodExecutionInTraceCollector(List, String, int, String)���Ă΂ꂽ��!"); + if (methodExecutions == null || methodExecutions.isEmpty()) { + return count; + } + for (int i = 0; i < methodExecutions.size(); i++) { + MethodExecution me = methodExecutions.get(i); + String signature = me.getSignature(); +// System.out.println(indent + signature); + if (targetSignature.equals(signature)) { + count++; + } + List children = me.getChildren(); + count = countMethodExecutionInTraceCollector(children, targetSignature, count, indent + "--------"); + } + return count; + } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/OnlineTraceAnalyzerCallTester.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/OnlineTraceAnalyzerCallTester.java new file mode 100644 index 0000000..8662ced --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/OnlineTraceAnalyzerCallTester.java @@ -0,0 +1,31 @@ +package org.ntlab.reverseDebugger; + +import org.ntlab.debuggingControl.MethodCaller; + +import com.sun.jdi.ClassNotLoadedException; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.InvalidTypeException; +import com.sun.jdi.InvocationException; +import com.sun.jdi.ThreadReference; +import com.sun.jdi.VirtualMachine; + +/** + * �^�[�Q�b�g����VM��ɂ��邱�̃v���W�F�N�g���̃N���X�̃��\�b�h(���OnlineTraceAnalyzer�N���X�Ƃ��̃��\�b�h)�� + * reverseDebugger����VM��ɂ��邱�̃v���W�F�N�g���̃N���X�̃��\�b�h���s����Ăяo���e�X�g�p�N���X + * @author student + * + */ +public class OnlineTraceAnalyzerCallTester { + + public void test1(VirtualMachine vm, ThreadReference thread) { + System.out.println("OnlineTraceAnalyzerCaller#test1()���Ă΂ꂽ��!"); + MethodCaller mc = new MethodCaller(vm, thread); + try { + mc.callStaticMethod("org.ntlab.reverseDebugger", "OnlineTraceAnalyzer", "test2"); + } catch (InvalidTypeException | ClassNotLoadedException + | InvocationException | IncompatibleThreadStateException e) { + e.printStackTrace(); + } + System.out.println("OnlineTraceAnalyzerCaller#test1()���甲�����!"); + } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ReverseDebuggerLaunchConfiguration.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ReverseDebuggerLaunchConfiguration.java new file mode 100644 index 0000000..e11440e --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ReverseDebuggerLaunchConfiguration.java @@ -0,0 +1,26 @@ +package org.ntlab.reverseDebugger; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.FileLocator; +import org.ntlab.traceCollector.IAdditionalLaunchConfiguration; + +public class ReverseDebuggerLaunchConfiguration implements IAdditionalLaunchConfiguration { + public static final String ANALYZER_PATH = "org/ntlab/reverseDebugger/OnlineTraceAnalyzer.class"; + + @Override + public String[] getAdditionalClasspath() { + try { + List classPathList = new ArrayList<>(); + String tracerClassPath = FileLocator.resolve(this.getClass().getClassLoader().getResource(ANALYZER_PATH)).getPath(); + String classPath = tracerClassPath.substring(1, tracerClassPath.length() - ANALYZER_PATH.length()); + classPathList.add(classPath); + return classPathList.toArray(new String[classPathList.size()]); + } catch (IOException e) { + e.printStackTrace(); + } + throw new IllegalStateException(); + } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ReverseDebuggerPerspective.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ReverseDebuggerPerspective.java new file mode 100644 index 0000000..6cbde35 --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ReverseDebuggerPerspective.java @@ -0,0 +1,27 @@ +package org.ntlab.reverseDebugger; + +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; +import org.eclipse.ui.part.IPage; + +public class ReverseDebuggerPerspective implements IPerspectiveFactory { + + @Override + public void createInitialLayout(IPageLayout layout) { + // �G�f�B�^�̏ꏊ���擾 + String editorArea = layout.getEditorArea(); + + // ����ɃR�[���X�^�b�N�̃r���[��z�u + IFolderLayout topLeft = layout.createFolder("topLeft", IPageLayout.TOP, 0.35f, editorArea); + topLeft.addView(CallStackView.ID); + + // �E��ɃV�[�h�G�C���A�X�̃r���[��z�u + IFolderLayout topRight = layout.createFolder("topRight", IPageLayout.RIGHT, 0.5f, "topLeft"); + topRight.addView(SeedAliasView.ID); + + // �E���ɃI�u�W�F�N�g�t���[�G�C���A�X�̃r���[��z�u + IFolderLayout bottomRight = layout.createFolder("bottomRight", IPageLayout.RIGHT, 0.5f, editorArea); + bottomRight.addView(ObjectFlowAliasView.ID); + } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/SeedAliasLabelProvider.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/SeedAliasLabelProvider.java new file mode 100644 index 0000000..92c5a80 --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/SeedAliasLabelProvider.java @@ -0,0 +1,59 @@ +package org.ntlab.reverseDebugger; + +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; +import org.ntlab.debuggingControl.MethodCaller; + +import com.sun.jdi.ClassNotLoadedException; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.IntegerValue; +import com.sun.jdi.InvalidTypeException; +import com.sun.jdi.InvocationException; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.StringReference; +import com.sun.jdi.Value; + +public class SeedAliasLabelProvider extends LabelProvider implements ITableLabelProvider { + + @Override + public String getColumnText(Object element, int columnIndex) { + if (element instanceof MethodCaller) { + MethodCaller mc = (MethodCaller)element; + try { + switch (columnIndex) { + case 0: + return ((StringReference)mc.callInstanceMethod("getObjectId")).value(); + case 1: + return ((StringReference)mc.callInstanceMethod("getClassName")).value(); + case 2: + return ((StringReference)mc.callInstanceMethod("getMethodExecutionClassName")).value(); + case 3: + return String.valueOf(((IntegerValue)mc.callInstanceMethod("getLineNo")).value()); + case 4: + return ((StringReference)mc.callInstanceMethod("getStatementType")).value(); + case 5: + return ((StringReference)mc.callInstanceMethod("getStatementSignature")).value(); + case 6: + return ((StringReference)mc.callInstanceMethod("getOccurrenceText")).value(); + } + } catch (InvalidTypeException | ClassNotLoadedException + | InvocationException | IncompatibleThreadStateException e) { + e.printStackTrace(); + } + } + return "�e�X�g�p�e�L�X�g" + columnIndex; + } + + @Override + public Image getColumnImage(Object element, int columnIndex) { + return getImage(element); + } + + @Override + public Image getImage(Object element) { + return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT); + } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/SeedAliasView.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/SeedAliasView.java new file mode 100644 index 0000000..bd11e6f --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/SeedAliasView.java @@ -0,0 +1,181 @@ +package org.ntlab.reverseDebugger; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.ViewPart; +import org.ntlab.debuggingControl.MethodCaller; + +public class SeedAliasView extends ViewPart { + private static TableViewer viewer; + private IAction refreshAction; + private IAction resetAction; + private IAction getObjectFlowAction; + private MethodCaller selectSeedAlias; + private static SeedAliases seedAliases = new SeedAliases(); + private static JavaEditorOperator javaEditorOperator = new JavaEditorOperator(); + public static final String ID = "org.ntlab.reverseDebugger.seedAliasView"; + + public SeedAliasView() { + // TODO Auto-generated constructor stub + System.out.println("SeedAliasView�N���X���������ꂽ��!"); + } + + @Override + public void createPartControl(Composite parent) { + // TODO Auto-generated method stub + System.out.println("SeedAliasView#createPartControl(Composite)���Ă΂ꂽ��!"); + viewer = new TableViewer(parent, SWT.FULL_SELECTION); + Table table = viewer.getTable(); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + // �e�[�u���̃J�������쐬 + String[] tableColumnTexts = {"objectID", "objectType", "srcFile", "lineNo", "statementType", "statementSignature", "occurrence"}; + int[] tableColumnWidth = {150, 160, 160, 80, 180, 300, 110}; + TableColumn[] tableColumns = new TableColumn[tableColumnTexts.length]; + for (int i = 0; i < tableColumns.length; i++) { + tableColumns[i] = new TableColumn(table, SWT.NULL); + tableColumns[i].setText(tableColumnTexts[i]); + tableColumns[i].setWidth(tableColumnWidth[i]); + } + viewer.setContentProvider(new ArrayContentProvider()); + viewer.setLabelProvider(new SeedAliasLabelProvider()); + viewer.setInput(seedAliases.getSeedAliases()); + CallStackView.refresh(); + + // �I�������J�����ɑΉ�����V�[�h�G�C���A�X���t�B�[���h�ɋL�^���Ă������X�i�[��o�^ (�I��������ɉE�N���b�N�ŃI�u�W�F�N�g�t���[�����s������ۂɕK�v) + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + IStructuredSelection sel = (IStructuredSelection)event.getSelection(); + Object element = sel.getFirstElement(); + if (element instanceof MethodCaller) { + selectSeedAlias = (MethodCaller)element; + javaEditorOperator.openSrcFileOfAlias(selectSeedAlias); + } + } + }); + + createActions(); + createToolBar(); + createMenuBar(); + createPopupMenu(); + } + + @Override + public void setFocus() { + // TODO Auto-generated method stub + viewer.getControl().setFocus(); + } + + private void createActions() { + refreshAction = new Action() { + @Override + public void run() { + refresh(); + } + }; + refreshAction.setText("refresh"); + refreshAction.setToolTipText("refresh"); + refreshAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ELCL_SYNCED)); + + resetAction = new Action() { + @Override + public void run() { + reset(); + } + }; + resetAction.setText("reset"); + resetAction.setToolTipText("reset"); + resetAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ETOOL_HOME_NAV)); + + getObjectFlowAction = new Action() { + @Override + public void run() { + getObjectFlow(); + } + }; + getObjectFlowAction.setText("getObjectFlow"); + getObjectFlowAction.setToolTipText("getObjectFlow"); + getObjectFlowAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_TASK_TSK)); + } + + private void createToolBar() { + IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager(); + mgr.add(refreshAction); + mgr.add(resetAction); + } + + private void createMenuBar() { + IMenuManager mgr = getViewSite().getActionBars().getMenuManager(); + mgr.add(refreshAction); + mgr.add(resetAction); + } + + private void createPopupMenu() { + MenuManager menuMgr = new MenuManager("#PopupMenu"); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + @Override + public void menuAboutToShow(IMenuManager manager) { + manager.add(getObjectFlowAction); + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + }); + Menu menu = menuMgr.createContextMenu(viewer.getControl()); + viewer.getControl().setMenu(menu); + getSite().registerContextMenu(menuMgr, viewer); + } + + public static MethodCaller getDebuggerStopMethodExecution() { + return seedAliases.getDebuggerStopMethodExecution(); + } + + public static void createSeedAliasesByAlias(MethodCaller alias) { + seedAliases.createSeedAliasesByAlias(alias); + } + + public static void createSeedAliasesByMethodExecution(MethodCaller methodExecution) { + seedAliases.createSeedAliasesByMethodExecution(methodExecution); + } + + public static void refresh() { + if (seedAliases.getSeedAliases().isEmpty()) { + seedAliases.initSeedAliases(); + javaEditorOperator.openSrcFileOfMethodExecution(seedAliases.getDebuggerStopMethodExecution()); + CallStackView.reset(); + } + viewer.refresh(); + } + + private void reset() { + seedAliases.reset(); + ObjectFlowAliasView.reset(); + refresh(); + } + + private void getObjectFlow() { + if (selectSeedAlias != null) { + ObjectFlowAliasView.createObjectFlow(selectSeedAlias); + ObjectFlowAliasView.refresh(); + } + } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/SeedAliases.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/SeedAliases.java new file mode 100644 index 0000000..6157dfb --- /dev/null +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/SeedAliases.java @@ -0,0 +1,157 @@ +package org.ntlab.reverseDebugger; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; + +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.internal.core.LaunchManager; +import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.MessageDialog; +import org.ntlab.debuggingControl.MethodCaller; + +import com.sun.jdi.ClassNotLoadedException; +import com.sun.jdi.ClassType; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.IntegerValue; +import com.sun.jdi.InvalidTypeException; +import com.sun.jdi.InvocationException; +import com.sun.jdi.Location; +import com.sun.jdi.LongValue; +import com.sun.jdi.Method; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.ReferenceType; +import com.sun.jdi.StackFrame; +import com.sun.jdi.StringReference; +import com.sun.jdi.ThreadReference; +import com.sun.jdi.Value; +import com.sun.jdi.VirtualMachine; + +public class SeedAliases { + private MethodCaller debuggerStopMethodExecution = null; + private List seedAliases = new ArrayList<>(); + private static final String TRACER = "org.ntlab.traceCollector.tracer.trace"; + private static final String ANALYZER = "org.ntlab.reverseDebugger"; + + public SeedAliases() { + initSeedAliases(); + } + + public MethodCaller getDebuggerStopMethodExecution() { + return debuggerStopMethodExecution; + } + + public List getSeedAliases() { + return seedAliases; + } + + public void reset() { + seedAliases.clear(); + } + + public void initSeedAliases() { + // TODO Auto-generated method stub + LaunchManager lm = (LaunchManager)DebugPlugin.getDefault().getLaunchManager(); + + ILaunch[] launches = lm.getLaunches(); + if (launches.length != 0) { + ILaunch debugLaunch = null; + for (int i = 0; i < launches.length; i++) { + System.out.print(launches[i].getLaunchConfiguration().getName() + ":"); + System.out.print(launches[i].getDebugTarget()); + if (launches[i].getDebugTarget() != null) { + debugLaunch = launches[i]; + break; + } + } + if (debugLaunch != null) { + JDIDebugTarget debugTarget = ((JDIDebugTarget)debugLaunch.getDebugTarget()); + VirtualMachine vm = debugTarget.getVM(); + if (vm != null) { + // �f�o�b�O���s���̏ꍇ + List allThreads = vm.allThreads(); + for (int i = 0; i < allThreads.size(); i++) { + ThreadReference thread = allThreads.get(i); + if (thread.isSuspended()) { + createSeedAliases(vm, thread); + } + } + } + } + } + } + + /** + * ���݃f�o�b�K�Ŏ~�܂��Ă���n�_�ł̃��\�b�h���s���̑S�V�[�h�G�C���A�X�ꗗ���Z�b�g���� + * @param vm + * @param thread + */ + private void createSeedAliases(VirtualMachine vm, ThreadReference thread) { + MethodCaller mc = new MethodCaller(vm, thread); + try { + // threadId�̎擾��StringReference�^�ւ̕ϊ� + Value threadIdValue = mc.setObj(thread).callInstanceMethod("getId"); + StringReference threadId = vm.mirrorOf(String.valueOf(((LongValue)threadIdValue).value())); + + // threadId�ɑΉ�����ThreadInstance���擾 + ObjectReference threadInstance = (ObjectReference)mc.callStaticMethod(TRACER, "TraceJSON", "getThreadInstance", threadId); + Value methodExecution = mc.setObj(threadInstance).callInstanceMethod("getCurrentMethodExecution"); + debuggerStopMethodExecution = new MethodCaller(vm, thread, (ObjectReference)methodExecution); + findAllSeedAlias(vm, thread, methodExecution); + } catch (InvalidTypeException | ClassNotLoadedException | InvocationException | IncompatibleThreadStateException e) { + e.printStackTrace(); + } + } + + /** + * �n���ꂽ�G�C���A�X�������Ă��郁�\�b�h���s���̑S�V�[�h�G�C���A�X�̈ꗗ���Z�b�g���� + * @param alias + */ + public void createSeedAliasesByAlias(MethodCaller alias) { + VirtualMachine vm = alias.getVm(); + ThreadReference thread = alias.getThread(); + MethodCaller mc = new MethodCaller(vm, thread); + try { + Value methodExecution = alias.callInstanceMethod("getMethodExecution"); + findAllSeedAlias(vm, thread, methodExecution); + } catch (InvalidTypeException | ClassNotLoadedException + | InvocationException | IncompatibleThreadStateException e) { + e.printStackTrace(); + } + } + + /** + * �n���ꂽ���\�b�h���s���̑S�V�[�h�G�C���A�X�̈ꗗ���Z�b�g���� + * @param methodExecution + */ + public void createSeedAliasesByMethodExecution(MethodCaller methodExecution) { + try { + findAllSeedAlias(methodExecution.getVm(), methodExecution.getThread(), methodExecution.getObj()); + } catch (InvalidTypeException | ClassNotLoadedException + | InvocationException | IncompatibleThreadStateException e) { + e.printStackTrace(); + } + } + + /** + * �n���ꂽ���\�b�h���s���̑S�V�[�h�G�C���A�X�̈ꗗ��, ���ۂ�traceCollector���ƒʐM���Ď擾���Z�b�g���� + * @param vm + * @param thread + * @param methodExecution + */ + private void findAllSeedAlias(VirtualMachine vm, ThreadReference thread, Value methodExecution) throws InvalidTypeException, + ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { + MethodCaller mc = new MethodCaller(vm, thread); + seedAliases.clear(); +// ObjectReference seedAliasList = (ObjectReference)mc.callStaticMethod(TRACER, "TraceJSON", "findAllStartAlias", methodExecution); + ObjectReference seedAliasList = (ObjectReference)mc.callStaticMethod(ANALYZER, "OnlineTraceAnalyzer", "findAllStartAlias", methodExecution); + int seedAliasListSize = ((IntegerValue)mc.setObj(seedAliasList).callInstanceMethod("size")).value(); + for (int i = 0; i < seedAliasListSize; i++) { + ObjectReference seedAlias = (ObjectReference)mc.setObj(seedAliasList).callInstanceMethod("get", vm.mirrorOf(i)); + seedAliases.add(new MethodCaller(vm, thread, seedAlias)); + } + } +} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackLabelProvider.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackLabelProvider.java deleted file mode 100644 index de53070..0000000 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackLabelProvider.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.ntlab.reversedebugger; - -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.TreeNode; -import org.eclipse.swt.graphics.Image; -import org.eclipse.ui.ISharedImages; -import org.eclipse.ui.PlatformUI; -import org.ntlab.debuggingControl.MethodCaller; - -import com.sun.jdi.ClassNotLoadedException; -import com.sun.jdi.IncompatibleThreadStateException; -import com.sun.jdi.InvalidTypeException; -import com.sun.jdi.InvocationException; -import com.sun.jdi.ObjectReference; -import com.sun.jdi.StringReference; -import com.sun.jdi.ThreadReference; - -public class CallStackLabelProvider extends LabelProvider { - - @Override - public String getText(Object element) { - if (element instanceof TreeNode) { - Object value = ((TreeNode)element).getValue(); - if (value instanceof MethodCaller) { - MethodCaller mc = (MethodCaller)value; - return "ThreadID: " + mc.getThreadId(); - } - if (value instanceof CallStackModel) { - CallStackModel callStackModel = (CallStackModel)value; - StringBuilder text = new StringBuilder(); - text.append(callStackModel.getSignature()); - text.append(" line: "); - text.append(callStackModel.getCallLineNo()); - return text.toString(); - } - } - return ""; - } - - @Override - public Image getImage(Object element) { - if (element instanceof TreeNode) { - return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT); - } - return null; - } -} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackModel.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackModel.java deleted file mode 100644 index c5503b5..0000000 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackModel.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.ntlab.reversedebugger; - -import org.ntlab.debuggingControl.MethodCaller; - -import com.sun.jdi.ClassNotLoadedException; -import com.sun.jdi.IncompatibleThreadStateException; -import com.sun.jdi.IntegerValue; -import com.sun.jdi.InvalidTypeException; -import com.sun.jdi.InvocationException; -import com.sun.jdi.ObjectReference; -import com.sun.jdi.StringReference; -import com.sun.jdi.ThreadReference; -import com.sun.jdi.Value; -import com.sun.jdi.VirtualMachine; - -public class CallStackModel { - private MethodCaller methodExecutionMc; - private int callLineNo; - - public CallStackModel(VirtualMachine vm, ThreadReference thread, ObjectReference methodExecution, int callLineNo) { - methodExecutionMc = new MethodCaller(vm, thread, methodExecution); - this.callLineNo = callLineNo; - } - - public VirtualMachine getVm() { - return methodExecutionMc.getVm(); - } - - public ThreadReference getThread() { - return methodExecutionMc.getThread(); - } - - public MethodCaller getMethodCaller() { - return methodExecutionMc; - } - - public int getCallLineNo() { - return callLineNo; - } - - public String getSignature() { - String signature = ""; - try { - signature = ((StringReference)methodExecutionMc.callInstanceMethod("getSignature")).value(); - } catch (InvalidTypeException | ClassNotLoadedException - | InvocationException | IncompatibleThreadStateException e) { - e.printStackTrace(); - } - return signature; - } - - public Value callInstanceMethod(String methodName, Value... args) - throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { - return methodExecutionMc.callInstanceMethod(methodName, args); - } -} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackModels.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackModels.java deleted file mode 100644 index 971ae7a..0000000 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackModels.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.ntlab.reversedebugger; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.viewers.TreeNode; -import org.ntlab.debuggingControl.MethodCaller; - -import com.sun.jdi.ClassNotLoadedException; -import com.sun.jdi.IncompatibleThreadStateException; -import com.sun.jdi.IntegerValue; -import com.sun.jdi.InvalidTypeException; -import com.sun.jdi.InvocationException; -import com.sun.jdi.ObjectReference; -import com.sun.jdi.ThreadReference; -import com.sun.jdi.Value; -import com.sun.jdi.VirtualMachine; -import com.sun.jdi.event.MethodEntryEvent; - -public class CallStackModels { - private List callStackModels = new ArrayList<>(); - - public List getCallStackModels() { - return callStackModels; - } - - public TreeNode[] getCallStackModelsTreeNodes() { - TreeNode[] roots = new TreeNode[1]; - if (callStackModels.isEmpty()) { - return roots; - } - CallStackModel callStackModel = callStackModels.get(0); - roots[0] = new TreeNode(new MethodCaller(callStackModel.getVm(), callStackModel.getThread())); - TreeNode parentNode = roots[0]; - TreeNode[] childrenNode = new TreeNode[callStackModels.size()]; - parentNode.setChildren(childrenNode); - for (int i = 0; i < callStackModels.size(); i++) { - TreeNode childNode = new TreeNode(callStackModels.get(i)); - childNode.setParent(parentNode); - childrenNode[i] = childNode; - } - return roots; - } - - public void reset() { - callStackModels.clear(); - } - - public void updateByDebuggerStopMethodExecution(MethodCaller me) { - if (me == null) { - return; - } - try { - VirtualMachine vm = me.getVm(); - ThreadReference thread = me.getThread(); - int lineNo = thread.frame(0).location().lineNumber(); - update(vm, thread, me.getObj(), lineNo); - } catch (InvalidTypeException | ClassNotLoadedException - | InvocationException | IncompatibleThreadStateException e) { - e.printStackTrace(); - } - } - - public void updateByAlias(MethodCaller alias) { - if (alias == null) { - return; - } - VirtualMachine vm = alias.getVm(); - ThreadReference thread = alias.getThread(); - try { - ObjectReference me = (ObjectReference)alias.callInstanceMethod("getMethodExecution"); - int lineNo = ((IntegerValue)alias.callInstanceMethod("getLineNo")).value(); - update(vm, thread, me, lineNo); - } catch (InvalidTypeException | ClassNotLoadedException - | InvocationException | IncompatibleThreadStateException e) { - e.printStackTrace(); - } - } - - private void update(VirtualMachine vm, ThreadReference thread, ObjectReference me, int topMethodCallLineNo) - throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { - callStackModels.clear(); - ObjectReference childMe = null; - int callLineNo = topMethodCallLineNo; - while (me != null) { - CallStackModel callStackModel = new CallStackModel(vm, thread, me, callLineNo); - callStackModels.add(callStackModel); - childMe = me; - me = (ObjectReference)callStackModel.callInstanceMethod("getParent"); - if (me != null) { - MethodCaller mc = new MethodCaller(vm, thread, me); - ObjectReference callStatement = (ObjectReference)mc.callInstanceMethod("getMethodInvocation", childMe); - callLineNo = ((IntegerValue)mc.setObj(callStatement).callInstanceMethod("getLineNo")).value(); - } - } - } -} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackView.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackView.java deleted file mode 100644 index ce7e090..0000000 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackView.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.ntlab.reversedebugger; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.TreeNode; -import org.eclipse.jface.viewers.TreeNodeContentProvider; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.ISharedImages; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.part.ViewPart; -import org.ntlab.debuggingControl.MethodCaller; - -public class CallStackView extends ViewPart { - private static TreeViewer viewer; - private IAction refreshAction; - private static CallStackModels callStackModels = new CallStackModels(); - private JavaEditorOperator javaEditorOperator = new JavaEditorOperator(); - public static final String ID = "org.ntlab.reverseDebugger.callStackView"; - - public CallStackView() { - // TODO Auto-generated constructor stub - System.out.println("callStackView�N���X���������ꂽ��"); - } - - @Override - public void createPartControl(Composite parent) { - // TODO Auto-generated method stub - System.out.println("CallStackView#createPartControl(Composite)���Ă΂ꂽ��!"); - viewer = new TreeViewer(parent); - viewer.setContentProvider(new TreeNodeContentProvider()); - viewer.setLabelProvider(new CallStackLabelProvider()); - viewer.expandAll(); - - // �I�������J�����ɑΉ����郁�\�b�h���s�̃\�[�X�t�@�C�����J�����郊�X�i�[��o�^���� - viewer.addSelectionChangedListener(new ISelectionChangedListener() { - @Override - public void selectionChanged(SelectionChangedEvent event) { - IStructuredSelection sel = (IStructuredSelection)event.getSelection(); - Object element = sel.getFirstElement(); - if (element instanceof TreeNode) { - Object value = ((TreeNode)element).getValue(); - if (value instanceof CallStackModel) { - MethodCaller methodExecution = ((CallStackModel)value).getMethodCaller(); - SeedAliasView.createSeedAliasesByMethodExecution(methodExecution); - SeedAliasView.refresh(); - javaEditorOperator.openSrcFileOfMethodExecution(methodExecution); - } - } - } - }); - createActions(); - createToolBar(); - createMenuBar(); - } - - @Override - public void setFocus() { - // TODO Auto-generated method stub - viewer.getControl().setFocus(); - } - - private void createActions() { - refreshAction = new Action() { - @Override - public void run() { - refresh(); - } - }; - refreshAction.setText("refresh"); - refreshAction.setToolTipText("refresh"); - refreshAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ELCL_SYNCED)); - } - - private void createToolBar() { - IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager(); - mgr.add(refreshAction); - } - - private void createMenuBar() { - IMenuManager mgr = getViewSite().getActionBars().getMenuManager(); - mgr.add(refreshAction); - } - - public static void updateByAlias(MethodCaller alias) { - callStackModels.updateByAlias(alias); - } - - public static void refresh() { - if (callStackModels.getCallStackModels().isEmpty()) { - MethodCaller currentMe = SeedAliasView.getDebuggerStopMethodExecution(); - callStackModels.updateByDebuggerStopMethodExecution(currentMe); - } - TreeNode[] nodes = callStackModels.getCallStackModelsTreeNodes(); - if (nodes == null || nodes[0] == null) { - return; - } - viewer.setInput(nodes); - viewer.expandAll(); - } - - public static void reset() { - callStackModels.reset(); - refresh(); - } -} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/JavaEditorOperator.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/JavaEditorOperator.java deleted file mode 100644 index 33a603e..0000000 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/JavaEditorOperator.java +++ /dev/null @@ -1,219 +0,0 @@ -package org.ntlab.reversedebugger; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IMethod; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.core.Signature; -import org.eclipse.jdt.ui.JavaUI; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.PartInitException; -import org.ntlab.debuggingControl.MethodCaller; - -import com.sun.jdi.ClassNotLoadedException; -import com.sun.jdi.IncompatibleThreadStateException; -import com.sun.jdi.InvalidTypeException; -import com.sun.jdi.InvocationException; -import com.sun.jdi.ObjectReference; -import com.sun.jdi.StringReference; -import com.sun.jdi.ThreadReference; -import com.sun.jdi.Value; -import com.sun.jdi.VirtualMachine; - -public class JavaEditorOperator { - private static final String TRACE = "org.ntlab.traceCollector.tracer.trace"; - - public void openSrcFileOfAlias(MethodCaller alias) { - try { - ObjectReference methodExecution = (ObjectReference)alias.callInstanceMethod("getMethodExecution"); - MethodCaller meCaller = new MethodCaller(alias.getVm(), alias.getThread(), methodExecution); - openSrcFileOfMethodExecution(meCaller); - } catch (InvalidTypeException | ClassNotLoadedException - | InvocationException | IncompatibleThreadStateException e) { - e.printStackTrace(); - } - } - - /** - * �����œn����meCaller���ɂ���methodExecution����`����Ă���N���X�̃\�[�X�R�[�h��Ώ�Eclipse�̃G�f�B�^�ŊJ������ - * - * @param meCaller - */ - public void openSrcFileOfMethodExecution(MethodCaller meCaller) { - try { - IType type = findIType(meCaller); - if (type != null) { - IMethod method = findIMethod(meCaller, type); - if (method != null) { - openSrcFileOfIMethod(type, method); - } - } - } catch (InvalidTypeException | ClassNotLoadedException - | InvocationException | IncompatibleThreadStateException e) { - e.printStackTrace(); - } - } - - /** - * �����œn����IType��IMethod�ɑΉ�����\�[�X�R�[�h��Ώ�Eclipse�̃G�f�B�^�ŊJ������ - * - * @param type - * @param method - */ - private void openSrcFileOfIMethod(IType type, IMethod method) throws InvalidTypeException, ClassNotLoadedException, - InvocationException, IncompatibleThreadStateException { - openInJavaEditor(type, method); - } - - private IType findIType(MethodCaller meCaller) throws InvalidTypeException, - ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { - StringReference declaringClassName = (StringReference)meCaller.callInstanceMethod("getDeclaringClassName"); - String projectPath = getLoaderPath(meCaller, declaringClassName); - IType type = null; - if (projectPath != null) { - IJavaProject javaProject = findJavaProject(projectPath); - if (javaProject != null) { - StringReference methodSignature = (StringReference)meCaller.callInstanceMethod("getSignature"); - try { - type = javaProject.findType(declaringClassName.value()); - } catch (JavaModelException e) { - e.printStackTrace(); - } - } - } - return type; - } - - private String getLoaderPath(MethodCaller meCaller, StringReference declaringClassName) - throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { - ObjectReference classInfo = (ObjectReference)meCaller.callStaticMethod(TRACE, "TraceJSON", "getClassInfo", declaringClassName); - if (classInfo == null) { - declaringClassName = (StringReference)meCaller.callInstanceMethod("getThisClassName"); - classInfo = (ObjectReference)meCaller.callStaticMethod(TRACE, "TraceJSON", "getClassInfo", declaringClassName); - } - String loaderPath = null; - if (classInfo != null) { - // �Ȃ���loaderPath���擾�ł��Ă��Ȃ����߁A���ۂɏo�͂����JSON�g���[�X���Q�l�ɂ���path����^���Ă݂� - MethodCaller classInfoMethodCaller = new MethodCaller(meCaller.getVm(), meCaller.getThread(), classInfo); - String path = ((StringReference)classInfoMethodCaller.callInstanceMethod("getPath")).value(); - String declaringClassNameString = declaringClassName.value().replace(".", "/"); - loaderPath = path.substring(0, path.indexOf(declaringClassNameString)); // path����N���X�̊��S���薼�ȍ~��S�ĊO�������̂�projectPath�ɂ��Ă݂� - } - return loaderPath; - } - - private IJavaProject findJavaProject(String projectPath) { - IJavaProject javaProject = null; - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - IProject[] projects = root.getProjects(); - for (IProject project : projects) { - if (checkProjectPath(project, projectPath)) { - javaProject = JavaCore.create(project); - break; - } - } - return javaProject; - } - - private boolean checkProjectPath(IProject project, String projectPath) { - String projectLocation = project.getLocation().toString(); - if (projectPath.startsWith(projectLocation)) { - String[] projectPathSplit = projectPath.split(projectLocation); - return (projectPathSplit[1].charAt(0) == '/'); // �v���W�F�N�g���̑O����v�ɂ�鑼�v���W�F�N�g�Ƃ̌딻�������� - } - return false; - } - - private void openInJavaEditor(IType type, IMethod method) { - try { - if (type != null && method != null) { - IEditorPart editor = JavaUI.openInEditor(type); - if (!type.isLocal() && !type.isMember()) { - JavaUI.revealInEditor(editor, (IJavaElement) method); - } - } - } catch (PartInitException | JavaModelException e) { - e.printStackTrace(); - } - } - - private IMethod findIMethod(MethodCaller meCaller, IType type) throws InvalidTypeException, - ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { - IMethod method = null; - if (type != null) { - StringReference methodSignature = (StringReference)meCaller.callInstanceMethod("getSignature"); - method = findIMethod(type, methodSignature.value()); - } - return method; - } - - private IMethod findIMethod(IType type, String methodSignature) { - try { - for (IMethod method : type.getMethods()) { - if (checkMethodSignature(type, method, methodSignature)) { - return method; - } - } - } catch (JavaModelException e) { - e.printStackTrace(); - } - return null; - } - - private boolean checkMethodSignature(IType type, IMethod method, String methodSignature) { - String fqcn = type.getFullyQualifiedName(); - try { - StringBuilder jdtMethodSignature = new StringBuilder(); - jdtMethodSignature.append((method.isConstructor()) ? (fqcn + "(") : (fqcn + "." + method.getElementName() + "(")); - if (methodSignature.contains(jdtMethodSignature)) { - // ������v���Ă����ꍇ�Ɍ���A�������X�g����������ł���v���邩�ǂ����𔻒� (�I�[�o�[���[�h�ɂ��딻��������) - jdtMethodSignature.append(String.join(",", parseFQCNParameters(type, method)) + ")"); // �S�����̃V�O�l�`�������S����N���X���ɕϊ�����,�ŋ�؂��������� - return methodSignature.contains(jdtMethodSignature); - } - } catch (JavaModelException e) { - e.printStackTrace(); - } - return false; - } - - /** - * IMethod����擾�ł���S�����̃V�O�l�`�������S����N���X���ɒu�������Ċi�[�������X�g��Ԃ� - * - * @param type - * @param method - * @return - */ - private List parseFQCNParameters(IType type, IMethod method) throws JavaModelException { - List parameters = new ArrayList<>(); - for (String parameterType : method.getParameterTypes()) { - String readableType = Signature.toString(parameterType); // �V�O�l�`���̕�������^���̕�����ɕϊ� (�z��͌���[]���‚�) - String[] readableTypeSplit = { "", "" }; // �^����[]�̕����p - int firstBracketIndex = readableType.indexOf("[]"); - final int NO_BRACKET_INDEX = -1; - if (firstBracketIndex == NO_BRACKET_INDEX) { - readableTypeSplit[0] = readableType; // �^�� - } else { - readableTypeSplit[0] = readableType.substring(0, firstBracketIndex); // �^�� - readableTypeSplit[1] = readableType.substring(firstBracketIndex); // �^���̌���[]�S�� - } - String[][] resolveType = type.resolveType(readableTypeSplit[0]); // �p�b�P�[�W���ƃN���X���̑g�ݍ��킹���擾 - if (resolveType != null) { - if (resolveType[0][0].isEmpty()) { - readableTypeSplit[0] = (resolveType[0][1]); // �f�t�H���g�p�b�P�[�W�̏ꍇ�̓p�b�P�[�W����.�͓���Ȃ� - } else { - readableTypeSplit[0] = (resolveType[0][0] + "." + resolveType[0][1]); // ���S����N���X�� - } - } - parameters.add(readableTypeSplit[0] + readableTypeSplit[1]); - } - return parameters; - } -} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliasLabelProvider.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliasLabelProvider.java deleted file mode 100644 index 035e55b..0000000 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliasLabelProvider.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.ntlab.reversedebugger; - -import org.eclipse.jface.viewers.ITableLabelProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.swt.graphics.Image; -import org.eclipse.ui.ISharedImages; -import org.eclipse.ui.PlatformUI; -import org.ntlab.debuggingControl.MethodCaller; - -import com.sun.jdi.ClassNotLoadedException; -import com.sun.jdi.IncompatibleThreadStateException; -import com.sun.jdi.IntegerValue; -import com.sun.jdi.InvalidTypeException; -import com.sun.jdi.InvocationException; -import com.sun.jdi.ObjectReference; -import com.sun.jdi.StringReference; - -public class ObjectFlowAliasLabelProvider extends LabelProvider implements ITableLabelProvider { - - @Override - public String getColumnText(Object element, int columnIndex) { - if (element instanceof MethodCaller) { - MethodCaller mc = (MethodCaller)element; - if (mc.getObj() == null) { - return ""; - } - try { - switch (columnIndex) { - case 0: - return ((StringReference)mc.callInstanceMethod("getObjectId")).value(); - case 1: - return ((StringReference)mc.callInstanceMethod("getClassName")).value(); - case 2: - return ((StringReference)mc.callInstanceMethod("getMethodExecutionClassName")).value(); - case 3: - return String.valueOf(((IntegerValue)mc.callInstanceMethod("getLineNo")).value()); - case 4: - return ((StringReference)mc.callInstanceMethod("getStatementType")).value(); - case 5: - return ((StringReference)mc.callInstanceMethod("getStatementSignature")).value(); - case 6: - return ((StringReference)mc.callInstanceMethod("getOccurrenceText")).value(); - } - } catch (InvalidTypeException | ClassNotLoadedException - | InvocationException | IncompatibleThreadStateException e) { - e.printStackTrace(); - } - } - return "�e�X�g�p�e�L�X�g" + columnIndex; - } - - @Override - public Image getColumnImage(Object element, int columnIndex) { - return getImage(element); - } - - @Override - public Image getImage(Object element) { - return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT); - } -} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliasView.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliasView.java deleted file mode 100644 index 6dcbfcc..0000000 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliasView.java +++ /dev/null @@ -1,173 +0,0 @@ -package org.ntlab.reversedebugger; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.viewers.ArrayContentProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.ui.ISelectionListener; -import org.eclipse.ui.ISharedImages; -import org.eclipse.ui.IWorkbenchActionConstants; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.part.ViewPart; -import org.ntlab.debuggingControl.MethodCaller; - -public class ObjectFlowAliasView extends ViewPart { - private static TableViewer viewer; - private IAction refreshAction; - private IAction findSeedAliasesAction; - private MethodCaller selectObjectFlowAlias; - private static ObjectFlowAliases objectFlowAliases = new ObjectFlowAliases(); - private JavaEditorOperator javaEditorOperator = new JavaEditorOperator(); - public static final String ID = "org.ntlab.reverseDebugger.objectFlowAliasView"; - - public ObjectFlowAliasView() { - // TODO Auto-generated constructor stub - System.out.println("ObjectFlowView�N���X���������ꂽ��!"); - } - - @Override - public void createPartControl(Composite parent) { - // TODO Auto-generated method stub - System.out.println("ObjectFlowView#createPartControl(Composite)���Ă΂ꂽ��!"); - viewer = new TableViewer(parent, SWT.FULL_SELECTION); - Table table = viewer.getTable(); - table.setHeaderVisible(true); - table.setLinesVisible(true); - - // �e�[�u���̃J�������쐬 - String[] tableColumnTexts = {"objectID", "objectType", "srcFile", "lineNo", "statementType", "statementSignature", "occurrence"}; - int[] tableColumnWidth = {150, 160, 160, 80, 180, 300, 110}; - TableColumn[] tableColumns = new TableColumn[tableColumnTexts.length]; - for (int i = 0; i < tableColumns.length; i++) { - tableColumns[i] = new TableColumn(table, SWT.NULL); - tableColumns[i].setText(tableColumnTexts[i]); - tableColumns[i].setWidth(tableColumnWidth[i]); - } - viewer.setContentProvider(new ArrayContentProvider()); - viewer.setLabelProvider(new ObjectFlowAliasLabelProvider()); - viewer.setInput(objectFlowAliases.getObjectFlowSingleList(true)); - - // �I�������J�����ɑΉ�����G�C���A�X������郁�\�b�h���s���̑S�ẴV�[�h�G�C���A�X�̈ꗗ�𐶐����郊�X�i�[��o�^ -// viewer.addSelectionChangedListener(new ISelectionChangedListener() { -// @Override -// public void selectionChanged(SelectionChangedEvent event) { -// IStructuredSelection sel = (IStructuredSelection)event.getSelection(); -// Object element = sel.getFirstElement(); -// if (element instanceof MethodCaller) { -// MethodCaller alias = (MethodCaller)element; -// SeedAliasView.createSeedAliases(alias); -// SeedAliasView.refresh(); -// CallStackView.updateByAlias(alias); -// CallStackView.refresh(); -// javaEditorOperator.openSrcFileOfAlias(alias); -// } -// } -// }); - - viewer.addSelectionChangedListener(new ISelectionChangedListener() { - @Override - public void selectionChanged(SelectionChangedEvent event) { - IStructuredSelection sel = (IStructuredSelection)event.getSelection(); - Object element = sel.getFirstElement(); - if (element instanceof MethodCaller) { - selectObjectFlowAlias = (MethodCaller)element; - javaEditorOperator.openSrcFileOfAlias(selectObjectFlowAlias); - } - } - }); - - createActions(); - createToolBar(); - createMenuBar(); - createPopupMenu(); - } - - @Override - public void setFocus() { - // TODO Auto-generated method stub - viewer.getControl().setFocus(); - } - - private void createActions() { - refreshAction = new Action() { - @Override - public void run() { - refresh(); - } - }; - refreshAction.setText("refresh"); - refreshAction.setToolTipText("refresh"); - refreshAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ELCL_SYNCED)); - - findSeedAliasesAction = new Action() { - @Override - public void run() { - findSeedAliases(); - } - }; - findSeedAliasesAction.setText("findSeedAliases"); - findSeedAliasesAction.setToolTipText("findSeedAliases"); - findSeedAliasesAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_TASK_TSK)); - } - - private void createToolBar() { - IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager(); - mgr.add(refreshAction); - } - - private void createMenuBar() { - IMenuManager mgr = getViewSite().getActionBars().getMenuManager(); - mgr.add(refreshAction); - } - - private void createPopupMenu() { - MenuManager menuMgr = new MenuManager("#PopupMenu"); - menuMgr.setRemoveAllWhenShown(true); - menuMgr.addMenuListener(new IMenuListener() { - @Override - public void menuAboutToShow(IMenuManager manager) { - manager.add(findSeedAliasesAction); - manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - } - }); - Menu menu = menuMgr.createContextMenu(viewer.getControl()); - viewer.getControl().setMenu(menu); - getSite().registerContextMenu(menuMgr, viewer); - } - - public static void createObjectFlow(MethodCaller seedAlias) { - objectFlowAliases.createObjectFlow(seedAlias); - } - - private void findSeedAliases() { - SeedAliasView.createSeedAliasesByAlias(selectObjectFlowAlias); - SeedAliasView.refresh(); - CallStackView.updateByAlias(selectObjectFlowAlias); - CallStackView.refresh(); - javaEditorOperator.openSrcFileOfAlias(selectObjectFlowAlias); - } - - public static void refresh() { - viewer.setInput(objectFlowAliases.getObjectFlowSingleList(true)); - } - - public static void reset() { - objectFlowAliases.reset(); - viewer.setInput(objectFlowAliases.getObjectFlowSingleList(true)); - } -} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliases.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliases.java deleted file mode 100644 index 5b32580..0000000 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliases.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.ntlab.reversedebugger; - -import java.util.ArrayList; -import java.util.List; - -import org.ntlab.debuggingControl.MethodCaller; - -import com.sun.jdi.ClassNotLoadedException; -import com.sun.jdi.IncompatibleThreadStateException; -import com.sun.jdi.IntegerValue; -import com.sun.jdi.InvalidTypeException; -import com.sun.jdi.InvocationException; -import com.sun.jdi.ObjectReference; -import com.sun.jdi.Value; -import com.sun.jdi.VirtualMachine; - -public class ObjectFlowAliases { - private List> objectFlowAliases = new ArrayList<>(); - private static final String TRACE = "org.ntlab.traceCollector.tracer.trace"; - - public void reset() { - objectFlowAliases.clear(); - } - - public List> getObjectFlow() { - return objectFlowAliases; - } - - public List> getObjectFlow(MethodCaller seedAlias) { - createObjectFlow(seedAlias); - return objectFlowAliases; - } - - public List getObjectFlowSingleList(boolean hasBound) { - List list = new ArrayList<>(); - for (int i = 0; i < objectFlowAliases.size(); i++) { - for (int j = 0; j < objectFlowAliases.get(i).size(); j++) { - list.add(objectFlowAliases.get(i).get(j)); - } - if (hasBound) { - list.add(new MethodCaller(null, null)); // ���E�p�̃_�~�[�C���X�^���X�𐶐����Ēlj� - } - } - return list; - } - - public List getObjectFlowSingleList(MethodCaller seedAlias, boolean hasBound) { - createObjectFlow(seedAlias); - return getObjectFlowSingleList(hasBound); - } - - public void createObjectFlow(MethodCaller seedAlias) { - MethodCaller mc = new MethodCaller(seedAlias.getVm(), seedAlias.getThread()); - objectFlowAliases.clear(); - try { - // �I�������G�C���A�X���N�_�ɃI�u�W�F�N�g�t���[���Ăяo���Č��ʂ����X�g�Ŏ󂯎�� - ObjectReference aliasListsReference = (ObjectReference)seedAlias.callStaticMethod(TRACE, "TraceJSON", "getObjectFlow", seedAlias.getObj()); - - // �擾�������X�g�̒��g�����[�v�ʼn񂵂Ȃ�����o��, �Ǘ��p�̃��X�g�ɋl�ߒ��� - int aliasListsSize = ((IntegerValue)mc.setObj(aliasListsReference).callInstanceMethod("size")).value(); - for (int i = 0; i < aliasListsSize; i++) { - List list = new ArrayList<>(); - objectFlowAliases.add(list); - ObjectReference aliasListReference = (ObjectReference)mc.setObj(aliasListsReference).callInstanceMethod("get", mc.getVm().mirrorOf(i)); - int aliasListSize = ((IntegerValue)mc.setObj(aliasListReference).callInstanceMethod("size")).value(); - for (int j = 0; j < aliasListSize; j++) { - ObjectReference aliasReference = (ObjectReference)mc.setObj(aliasListReference).callInstanceMethod("get", mc.getVm().mirrorOf(j)); - list.add(new MethodCaller(seedAlias.getVm(), seedAlias.getThread(), aliasReference)); - } - } - } catch (InvalidTypeException | ClassNotLoadedException | InvocationException | IncompatibleThreadStateException e) { - e.printStackTrace(); - } - } -} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ReverseDebuggerPerspective.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ReverseDebuggerPerspective.java deleted file mode 100644 index c3b5584..0000000 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ReverseDebuggerPerspective.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.ntlab.reversedebugger; - -import org.eclipse.ui.IFolderLayout; -import org.eclipse.ui.IPageLayout; -import org.eclipse.ui.IPerspectiveFactory; -import org.eclipse.ui.part.IPage; - -public class ReverseDebuggerPerspective implements IPerspectiveFactory { - - @Override - public void createInitialLayout(IPageLayout layout) { - // �G�f�B�^�̏ꏊ���擾 - String editorArea = layout.getEditorArea(); - - // ����ɃR�[���X�^�b�N�̃r���[��z�u - IFolderLayout topLeft = layout.createFolder("topLeft", IPageLayout.TOP, 0.35f, editorArea); - topLeft.addView(CallStackView.ID); - - // �E��ɃV�[�h�G�C���A�X�̃r���[��z�u - IFolderLayout topRight = layout.createFolder("topRight", IPageLayout.RIGHT, 0.5f, "topLeft"); - topRight.addView(SeedAliasView.ID); - - // �E���ɃI�u�W�F�N�g�t���[�G�C���A�X�̃r���[��z�u - IFolderLayout bottomRight = layout.createFolder("bottomRight", IPageLayout.RIGHT, 0.5f, editorArea); - bottomRight.addView(ObjectFlowAliasView.ID); - } -} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliasLabelProvider.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliasLabelProvider.java deleted file mode 100644 index e686586..0000000 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliasLabelProvider.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.ntlab.reversedebugger; - -import org.eclipse.jface.viewers.ITableLabelProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.swt.graphics.Image; -import org.eclipse.ui.ISharedImages; -import org.eclipse.ui.PlatformUI; -import org.ntlab.debuggingControl.MethodCaller; - -import com.sun.jdi.ClassNotLoadedException; -import com.sun.jdi.IncompatibleThreadStateException; -import com.sun.jdi.IntegerValue; -import com.sun.jdi.InvalidTypeException; -import com.sun.jdi.InvocationException; -import com.sun.jdi.ObjectReference; -import com.sun.jdi.StringReference; -import com.sun.jdi.Value; - -public class SeedAliasLabelProvider extends LabelProvider implements ITableLabelProvider { - - @Override - public String getColumnText(Object element, int columnIndex) { - if (element instanceof MethodCaller) { - MethodCaller mc = (MethodCaller)element; - try { - switch (columnIndex) { - case 0: - return ((StringReference)mc.callInstanceMethod("getObjectId")).value(); - case 1: - return ((StringReference)mc.callInstanceMethod("getClassName")).value(); - case 2: - return ((StringReference)mc.callInstanceMethod("getMethodExecutionClassName")).value(); - case 3: - return String.valueOf(((IntegerValue)mc.callInstanceMethod("getLineNo")).value()); - case 4: - return ((StringReference)mc.callInstanceMethod("getStatementType")).value(); - case 5: - return ((StringReference)mc.callInstanceMethod("getStatementSignature")).value(); - case 6: - return ((StringReference)mc.callInstanceMethod("getOccurrenceText")).value(); - } - } catch (InvalidTypeException | ClassNotLoadedException - | InvocationException | IncompatibleThreadStateException e) { - e.printStackTrace(); - } - } - return "�e�X�g�p�e�L�X�g" + columnIndex; - } - - @Override - public Image getColumnImage(Object element, int columnIndex) { - return getImage(element); - } - - @Override - public Image getImage(Object element) { - return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT); - } -} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliasView.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliasView.java deleted file mode 100644 index 75d92d0..0000000 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliasView.java +++ /dev/null @@ -1,181 +0,0 @@ -package org.ntlab.reversedebugger; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.viewers.ArrayContentProvider; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.ui.ISharedImages; -import org.eclipse.ui.IWorkbenchActionConstants; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.part.ViewPart; -import org.ntlab.debuggingControl.MethodCaller; - -public class SeedAliasView extends ViewPart { - private static TableViewer viewer; - private IAction refreshAction; - private IAction resetAction; - private IAction getObjectFlowAction; - private MethodCaller selectSeedAlias; - private static SeedAliases seedAliases = new SeedAliases(); - private static JavaEditorOperator javaEditorOperator = new JavaEditorOperator(); - public static final String ID = "org.ntlab.reverseDebugger.seedAliasView"; - - public SeedAliasView() { - // TODO Auto-generated constructor stub - System.out.println("SeedAliasView�N���X���������ꂽ��!"); - } - - @Override - public void createPartControl(Composite parent) { - // TODO Auto-generated method stub - System.out.println("SeedAliasView#createPartControl(Composite)���Ă΂ꂽ��!"); - viewer = new TableViewer(parent, SWT.FULL_SELECTION); - Table table = viewer.getTable(); - table.setHeaderVisible(true); - table.setLinesVisible(true); - - // �e�[�u���̃J�������쐬 - String[] tableColumnTexts = {"objectID", "objectType", "srcFile", "lineNo", "statementType", "statementSignature", "occurrence"}; - int[] tableColumnWidth = {150, 160, 160, 80, 180, 300, 110}; - TableColumn[] tableColumns = new TableColumn[tableColumnTexts.length]; - for (int i = 0; i < tableColumns.length; i++) { - tableColumns[i] = new TableColumn(table, SWT.NULL); - tableColumns[i].setText(tableColumnTexts[i]); - tableColumns[i].setWidth(tableColumnWidth[i]); - } - viewer.setContentProvider(new ArrayContentProvider()); - viewer.setLabelProvider(new SeedAliasLabelProvider()); - viewer.setInput(seedAliases.getSeedAliases()); - CallStackView.refresh(); - - // �I�������J�����ɑΉ�����V�[�h�G�C���A�X���t�B�[���h�ɋL�^���Ă������X�i�[��o�^ (�I��������ɉE�N���b�N�ŃI�u�W�F�N�g�t���[�����s������ۂɕK�v) - viewer.addSelectionChangedListener(new ISelectionChangedListener() { - @Override - public void selectionChanged(SelectionChangedEvent event) { - IStructuredSelection sel = (IStructuredSelection)event.getSelection(); - Object element = sel.getFirstElement(); - if (element instanceof MethodCaller) { - selectSeedAlias = (MethodCaller)element; - javaEditorOperator.openSrcFileOfAlias(selectSeedAlias); - } - } - }); - - createActions(); - createToolBar(); - createMenuBar(); - createPopupMenu(); - } - - @Override - public void setFocus() { - // TODO Auto-generated method stub - viewer.getControl().setFocus(); - } - - private void createActions() { - refreshAction = new Action() { - @Override - public void run() { - refresh(); - } - }; - refreshAction.setText("refresh"); - refreshAction.setToolTipText("refresh"); - refreshAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ELCL_SYNCED)); - - resetAction = new Action() { - @Override - public void run() { - reset(); - } - }; - resetAction.setText("reset"); - resetAction.setToolTipText("reset"); - resetAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ETOOL_HOME_NAV)); - - getObjectFlowAction = new Action() { - @Override - public void run() { - getObjectFlow(); - } - }; - getObjectFlowAction.setText("getObjectFlow"); - getObjectFlowAction.setToolTipText("getObjectFlow"); - getObjectFlowAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_TASK_TSK)); - } - - private void createToolBar() { - IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager(); - mgr.add(refreshAction); - mgr.add(resetAction); - } - - private void createMenuBar() { - IMenuManager mgr = getViewSite().getActionBars().getMenuManager(); - mgr.add(refreshAction); - mgr.add(resetAction); - } - - private void createPopupMenu() { - MenuManager menuMgr = new MenuManager("#PopupMenu"); - menuMgr.setRemoveAllWhenShown(true); - menuMgr.addMenuListener(new IMenuListener() { - @Override - public void menuAboutToShow(IMenuManager manager) { - manager.add(getObjectFlowAction); - manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - } - }); - Menu menu = menuMgr.createContextMenu(viewer.getControl()); - viewer.getControl().setMenu(menu); - getSite().registerContextMenu(menuMgr, viewer); - } - - public static MethodCaller getDebuggerStopMethodExecution() { - return seedAliases.getDebuggerStopMethodExecution(); - } - - public static void createSeedAliasesByAlias(MethodCaller alias) { - seedAliases.createSeedAliasesByAlias(alias); - } - - public static void createSeedAliasesByMethodExecution(MethodCaller methodExecution) { - seedAliases.createSeedAliasesByMethodExecution(methodExecution); - } - - public static void refresh() { - if (seedAliases.getSeedAliases().isEmpty()) { - seedAliases.initSeedAliases(); - javaEditorOperator.openSrcFileOfMethodExecution(seedAliases.getDebuggerStopMethodExecution()); - CallStackView.reset(); - } - viewer.refresh(); - } - - private void reset() { - seedAliases.reset(); - ObjectFlowAliasView.reset(); - refresh(); - } - - private void getObjectFlow() { - if (selectSeedAlias != null) { - ObjectFlowAliasView.createObjectFlow(selectSeedAlias); - ObjectFlowAliasView.refresh(); - } - } -} diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliases.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliases.java deleted file mode 100644 index e67a6ec..0000000 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliases.java +++ /dev/null @@ -1,155 +0,0 @@ -package org.ntlab.reversedebugger; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Scanner; - -import org.eclipse.debug.core.DebugPlugin; -import org.eclipse.debug.core.ILaunch; -import org.eclipse.debug.internal.core.LaunchManager; -import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.dialogs.MessageDialog; -import org.ntlab.debuggingControl.MethodCaller; - -import com.sun.jdi.ClassNotLoadedException; -import com.sun.jdi.ClassType; -import com.sun.jdi.IncompatibleThreadStateException; -import com.sun.jdi.IntegerValue; -import com.sun.jdi.InvalidTypeException; -import com.sun.jdi.InvocationException; -import com.sun.jdi.Location; -import com.sun.jdi.LongValue; -import com.sun.jdi.Method; -import com.sun.jdi.ObjectReference; -import com.sun.jdi.ReferenceType; -import com.sun.jdi.StackFrame; -import com.sun.jdi.StringReference; -import com.sun.jdi.ThreadReference; -import com.sun.jdi.Value; -import com.sun.jdi.VirtualMachine; - -public class SeedAliases { - private MethodCaller debuggerStopMethodExecution = null; - private List seedAliases = new ArrayList<>(); - private final String TRACER = "org.ntlab.traceCollector.tracer.trace"; - - public SeedAliases() { - initSeedAliases(); - } - - public MethodCaller getDebuggerStopMethodExecution() { - return debuggerStopMethodExecution; - } - - public List getSeedAliases() { - return seedAliases; - } - - public void reset() { - seedAliases.clear(); - } - - public void initSeedAliases() { - // TODO Auto-generated method stub - LaunchManager lm = (LaunchManager)DebugPlugin.getDefault().getLaunchManager(); - - ILaunch[] launches = lm.getLaunches(); - if (launches.length != 0) { - ILaunch debugLaunch = null; - for (int i = 0; i < launches.length; i++) { - System.out.print(launches[i].getLaunchConfiguration().getName() + ":"); - System.out.print(launches[i].getDebugTarget()); - if (launches[i].getDebugTarget() != null) { - debugLaunch = launches[i]; - break; - } - } - if (debugLaunch != null) { - JDIDebugTarget debugTarget = ((JDIDebugTarget)debugLaunch.getDebugTarget()); - VirtualMachine vm = debugTarget.getVM(); - if (vm != null) { - // �f�o�b�O���s���̏ꍇ - List allThreads = vm.allThreads(); - for (int i = 0; i < allThreads.size(); i++) { - ThreadReference thread = allThreads.get(i); - if (thread.isSuspended()) { - createSeedAliases(vm, thread); - } - } - } - } - } - } - - /** - * ���݃f�o�b�K�Ŏ~�܂��Ă���n�_�ł̃��\�b�h���s���̑S�V�[�h�G�C���A�X�ꗗ���Z�b�g���� - * @param vm - * @param thread - */ - private void createSeedAliases(VirtualMachine vm, ThreadReference thread) { - MethodCaller mc = new MethodCaller(vm, thread); - try { - // threadId�̎擾��StringReference�^�ւ̕ϊ� - Value threadIdValue = mc.setObj(thread).callInstanceMethod("getId"); - StringReference threadId = vm.mirrorOf(String.valueOf(((LongValue)threadIdValue).value())); - - // threadId�ɑΉ�����ThreadInstance���擾 - ObjectReference threadInstance = (ObjectReference)mc.callStaticMethod(TRACER, "TraceJSON", "getThreadInstance", threadId); - Value methodExecution = mc.setObj(threadInstance).callInstanceMethod("getCurrentMethodExecution"); - debuggerStopMethodExecution = new MethodCaller(vm, thread, (ObjectReference)methodExecution); - findAllSeedAlias(vm, thread, methodExecution); - } catch (InvalidTypeException | ClassNotLoadedException | InvocationException | IncompatibleThreadStateException e) { - e.printStackTrace(); - } - } - - /** - * �n���ꂽ�G�C���A�X�������Ă��郁�\�b�h���s���̑S�V�[�h�G�C���A�X�̈ꗗ���Z�b�g���� - * @param alias - */ - public void createSeedAliasesByAlias(MethodCaller alias) { - VirtualMachine vm = alias.getVm(); - ThreadReference thread = alias.getThread(); - MethodCaller mc = new MethodCaller(vm, thread); - try { - Value methodExecution = alias.callInstanceMethod("getMethodExecution"); - findAllSeedAlias(vm, thread, methodExecution); - } catch (InvalidTypeException | ClassNotLoadedException - | InvocationException | IncompatibleThreadStateException e) { - e.printStackTrace(); - } - } - - /** - * �n���ꂽ���\�b�h���s���̑S�V�[�h�G�C���A�X�̈ꗗ���Z�b�g���� - * @param methodExecution - */ - public void createSeedAliasesByMethodExecution(MethodCaller methodExecution) { - try { - findAllSeedAlias(methodExecution.getVm(), methodExecution.getThread(), methodExecution.getObj()); - } catch (InvalidTypeException | ClassNotLoadedException - | InvocationException | IncompatibleThreadStateException e) { - e.printStackTrace(); - } - } - - /** - * �n���ꂽ���\�b�h���s���̑S�V�[�h�G�C���A�X�̈ꗗ��, ���ۂ�traceCollector���ƒʐM���Ď擾���Z�b�g���� - * @param vm - * @param thread - * @param methodExecution - */ - private void findAllSeedAlias(VirtualMachine vm, ThreadReference thread, Value methodExecution) throws InvalidTypeException, - ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { - MethodCaller mc = new MethodCaller(vm, thread); - seedAliases.clear(); - ObjectReference seedAliasList = (ObjectReference)mc.callStaticMethod(TRACER, "TraceJSON", "findAllStartAlias", methodExecution); - int seedAliasListSize = ((IntegerValue)mc.setObj(seedAliasList).callInstanceMethod("size")).value(); - for (int i = 0; i < seedAliasListSize; i++) { - ObjectReference seedAlias = (ObjectReference)mc.setObj(seedAliasList).callInstanceMethod("get", vm.mirrorOf(i)); - seedAliases.add(new MethodCaller(vm, thread, seedAlias)); - } - } -}