diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliasView.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliasView.java index f8c7a19..abbb9ff 100644 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliasView.java +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliasView.java @@ -82,8 +82,12 @@ IStructuredSelection sel = (IStructuredSelection)event.getSelection(); Object element = sel.getFirstElement(); if (element instanceof JDIInstanceMethodCaller) { - selectObjectFlowAlias = (JDIInstanceMethodCaller)element; - javaEditorOperator.openSrcFileOfAlias(selectObjectFlowAlias); + if (((JDIInstanceMethodCaller)element).getReceiver() != null) { + selectObjectFlowAlias = (JDIInstanceMethodCaller)element; + javaEditorOperator.openSrcFileOfAlias(selectObjectFlowAlias); + } else { + selectObjectFlowAlias = null; + } } } }); @@ -152,11 +156,13 @@ } private void findSeedAliases() { - SeedAliasView.createSeedAliasesByAlias(selectObjectFlowAlias); - SeedAliasView.refresh(); - CallStackView.updateByAlias(selectObjectFlowAlias); - CallStackView.refresh(); - javaEditorOperator.openSrcFileOfAlias(selectObjectFlowAlias); + if (selectObjectFlowAlias != null) { + SeedAliasView.createSeedAliasesByAlias(selectObjectFlowAlias); + SeedAliasView.refresh(); + CallStackView.updateByAlias(selectObjectFlowAlias); + CallStackView.refresh(); + javaEditorOperator.openSrcFileOfAlias(selectObjectFlowAlias); + } } public static void refresh() { diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliases.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliases.java index 5e1f4a4..9cea0fa 100644 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliases.java +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/ObjectFlowAliases.java @@ -36,7 +36,7 @@ for (int j = 0; j < objectFlowAliases.get(i).size(); j++) { list.add(objectFlowAliases.get(i).get(j)); } - if (hasBound) { + if (hasBound && i < objectFlowAliases.size() - 1) { list.add(new JDIInstanceMethodCaller(null, null, null)); // ���E�p�̃_�~�[�C���X�^���X�𐶐����Ēlj� } } diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/SeedAliases.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/SeedAliases.java index c0c9e7c..bc236d0 100644 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/SeedAliases.java +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/SeedAliases.java @@ -122,7 +122,7 @@ ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { JDIInstanceMethodCaller mc = new JDIInstanceMethodCaller(vm, thread, null); seedAliases.clear(); - ObjectReference seedAliasList = (ObjectReference)mc.callStaticMethod(ReverseDebuggerLaunchConfiguration.ANALYZER_PACKAGE, ReverseDebuggerLaunchConfiguration.ANALYZER_CLASS, "findAllStartAlias", methodExecution); + ObjectReference seedAliasList = (ObjectReference)mc.callStaticMethod(ReverseDebuggerLaunchConfiguration.ANALYZER_PACKAGE, ReverseDebuggerLaunchConfiguration.ANALYZER_CLASS, "findAllSeedAliases", methodExecution); int seedAliasListSize = ((IntegerValue)mc.changeReceiver(seedAliasList).callInstanceMethod("size")).value(); for (int i = 0; i < seedAliasListSize; i++) { ObjectReference seedAlias = (ObjectReference)mc.changeReceiver(seedAliasList).callInstanceMethod("get", vm.mirrorOf(i)); diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/analyzerProvider/Alias.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/analyzerProvider/Alias.java index 86c9192..4100464 100644 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/analyzerProvider/Alias.java +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/analyzerProvider/Alias.java @@ -189,21 +189,32 @@ 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(); -// } + public boolean isOrigin() { + Statement statement = occurrencePoint.getStatement(); + if (statement instanceof MethodInvocation) { + MethodExecution calledMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution(); + return calledMethodExecution.isConstructor(); + } else if (statement instanceof ArrayCreate) { + return true; + } + return false; + } + + @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/analyzerProvider/ReverseDebuggerAnalyzer.java b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/analyzerProvider/ReverseDebuggerAnalyzer.java index 7939fc9..db2350a 100644 --- a/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/analyzerProvider/ReverseDebuggerAnalyzer.java +++ b/org.ntlab.reverseDebugger/src/org/ntlab/reverseDebugger/analyzerProvider/ReverseDebuggerAnalyzer.java @@ -19,8 +19,8 @@ public class ReverseDebuggerAnalyzer { - public static ArrayList findAllStartAlias(MethodExecution me) { - ArrayList startAliasList = new ArrayList<>(); + public static ArrayList findAllSeedAliases(MethodExecution me) { + ArrayList seedAliasList = new ArrayList<>(); List statements = me.getStatements(); String[] primitives = {"byte", "short", "int", "long", "float", "double", "char", "boolean"}; List primitiveList = Arrays.asList(primitives); @@ -31,64 +31,64 @@ 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)); + seedAliasList.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)); + seedAliasList.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)); + seedAliasList.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)); + seedAliasList.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)); + seedAliasList.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)); + seedAliasList.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)); + seedAliasList.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)); + seedAliasList.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))); + seedAliasList.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)); + seedAliasList.add(new Alias(returnValueId, tp, Alias.OCCURRENCE_EXP_RETURN)); } } } } - return startAliasList; + return seedAliasList; } private static TracePoint getRecentlyFieldUpdate(TracePoint tp) { @@ -120,15 +120,6 @@ 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���폜���� -// } -// } return resultLists; } @@ -158,6 +149,18 @@ aliasLists = getObjectFlow(aliasLists, objId, arrayUpdateTp, 0); aliasLists.add(aliasList); } + } else if (statement instanceof FieldUpdate) { + // �t�B�[���h�X�V�̏ꍇ + FieldUpdate fu = (FieldUpdate)statement; + if (fu.getValueObjId().equals(objId)) { + aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_FIELD)); + } + } else if (statement instanceof ArrayUpdate) { + // �z��v�f�X�V�̏ꍇ + ArrayUpdate au = (ArrayUpdate)statement; + if (au.getValueObjectId().equals(objId)) { + aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_ARRAY)); + } } else if (statement instanceof ArrayCreate) { // �z�񐶐��̏ꍇ ArrayCreate ac = (ArrayCreate)statement; @@ -171,6 +174,7 @@ ObjectReference returnValue = calledMethodExecution.getReturnValue(); if (returnValue.getId().equals(objId)) { // �߂�l�ɃG�C���A�X�̃I�u�W�F�N�gID����v�����ꍇ + ArrayList aliasListBeforeMethodBackEntry = new ArrayList<>(aliasList); // �Ăяo����̃��\�b�h���s�ɐ���O�̃G�C���A�X���X�g���R�s�[���Ă��� 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�ɂ͂����Ȃ��͂� @@ -178,6 +182,11 @@ 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); + if (aliasList.get(aliasList.size() - 1).isOrigin()) { + // �Ăяo����̃��\�b�h���s�ɐ�������ł��̃I�u�W�F�N�g�̋N��(�R���X�g���N�^or�z�񐶐�)�ɓ��B���Ă����ꍇ, �Ăяo����̃��\�b�h���s�ɐ���O�̃��X�g��p���ĐV�K�ɒǐՂ𑱍s���� + aliasLists.add(aliasListBeforeMethodBackEntry); + aliasList = aliasListBeforeMethodBackEntry; + } } } } while (tp.stepBackOver()); // �Ăяo�����ɖ߂邩����ȏ�H��Ȃ��Ȃ�܂Ń��[�v @@ -187,10 +196,12 @@ // --- ���̎��_�� tracePoint�� �Ăяo�������w���Ă��� (���O�܂ők���Ă������\�b�h���s�ɂ‚��Ẵ��\�b�h�Ăяo�����w���Ă���) --- MethodExecution calledMethodExecution = ((MethodInvocation)tp.getStatement()).getCalledMethodExecution(); ArrayList args = calledMethodExecution.getArguments(); + boolean isExistingInArgs = false; 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))); + isExistingInArgs = true; 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(); @@ -199,9 +210,12 @@ } } } + if (!isExistingInArgs) { + aliasLists.remove(aliasLists.size() - 1); // �����ɃG�C���A�X���Ȃ������ꍇ�͂��̉�̒ǐՃG�C���A�X���X�g���폜���� + } return aliasLists; } - + public static int countMethodExecutionInTraceCollector(List methodExecutions, String targetSignature, int count, String indent) { if (methodExecutions == null || methodExecutions.isEmpty()) { return count;