public JavaDebugDisassemblyStream(JavaDebugCodeContext executionContext) { Contract.Requires <ArgumentNullException>(executionContext != null, "executionContext"); _executionContext = executionContext; _bytecode = _executionContext.Location.GetMethod().GetBytecodes(); _disassembledMethod = BytecodeDisassembler.Disassemble(_bytecode); var constantPool = executionContext.Location.GetDeclaringType().GetConstantPool(); var exceptionTable = executionContext.Location.GetMethod().GetExceptionTable(); _evaluationStackDepths = BytecodeDisassembler.GetEvaluationStackDepths(_disassembledMethod, constantPool, exceptionTable); }
public JavaDebugDisassemblyStream(JavaDebugCodeContext executionContext) { Contract.Requires <ArgumentNullException>(executionContext != null, "executionContext"); _executionContext = executionContext; _bytecode = _executionContext.Location.GetMethod().GetBytecodes(); _disassembledMethod = BytecodeDisassembler.Disassemble(_bytecode); var constantPool = executionContext.Location.GetDeclaringType().GetConstantPool(); ReadOnlyCollection <ExceptionTableEntry> exceptionTable; try { exceptionTable = executionContext.Location.GetMethod().GetExceptionTable(); } catch (DebuggerException) { exceptionTable = new ReadOnlyCollection <ExceptionTableEntry>(new ExceptionTableEntry[0]); } _evaluationStackDepths = BytecodeDisassembler.GetEvaluationStackDepths(_disassembledMethod, constantPool, exceptionTable); }
private bool TryGetAssociatedTree(out IParseTree associatedTree, out IList <IToken> tokens) { try { string sourcePath = _location.GetSourcePath(); if (!File.Exists(sourcePath)) { associatedTree = null; tokens = null; return(false); } string text = File.ReadAllText(sourcePath); AntlrInputStream input = new AntlrInputStream(text); JavaLexer lexer = new JavaLexer(new JavaUnicodeStreamV4(input)); CommonTokenStream tokenStream = new CommonTokenStream(lexer); JavaParser parser = new JavaParser(tokenStream); parser.Interpreter.PredictionMode = PredictionMode.Sll; parser.BuildParseTree = true; JavaParser.CompilationUnitContext result = parser.compilationUnit(); associatedTree = null; tokens = tokenStream.GetTokens(); AssociatedTreeListener listener = new AssociatedTreeListener(_location, tokens); ParseTreeWalker.Default.Walk(listener, result); List <IParseTree> potentialTrees = listener.AssociatedTree; if (potentialTrees.Count == 1) { associatedTree = potentialTrees[0]; } else if (potentialTrees.Count > 1) { byte[] bytecode = _location.GetMethod().GetBytecodes(); DisassembledMethod disassembledMethod = BytecodeDisassembler.Disassemble(bytecode); var constantPool = _location.GetDeclaringType().GetConstantPool(); var exceptionTable = _location.GetMethod().GetExceptionTable(); ImmutableList <int?> evaluationStackDepths = BytecodeDisassembler.GetEvaluationStackDepths(disassembledMethod, constantPool, exceptionTable); ReadOnlyCollection <ILocation> locations = _location.GetMethod().GetLineLocations(); // find all bytecode offsets with evaluation stack depth 0 on the current line List <int> relevantOffsets = new List <int>(); for (int i = 0; i < locations.Count; i++) { if (locations[i].GetLineNumber() != _location.GetLineNumber()) { continue; } long offsetLimit = i < locations.Count - 1 ? locations[i + 1].GetCodeIndex() : bytecode.Length; // start with the instruction for this bytecode offset for (int j = GetInstructionAtOffset(disassembledMethod, locations[i].GetCodeIndex()); j >= 0 && j < disassembledMethod.Instructions.Count && disassembledMethod.Instructions[j].Offset < offsetLimit; j++) { if (evaluationStackDepths[j] == 0) { // ignore unconditional branches if (disassembledMethod.Instructions[j].OpCode.FlowControl == JavaFlowControl.Branch) { continue; } relevantOffsets.Add(disassembledMethod.Instructions[j].Offset); } } } if (relevantOffsets.Count == potentialTrees.Count) { // heuristic: assume they appear in the same order as the source code on this line int treeIndex = relevantOffsets.IndexOf((int)_location.GetCodeIndex()); if (treeIndex >= 0) { associatedTree = potentialTrees[treeIndex]; } } } if (associatedTree == null) { tokens = null; return(false); } return(true); } catch (Exception e) { if (ErrorHandler.IsCriticalException(e)) { throw; } associatedTree = null; tokens = null; return(false); } }
public StepEventFilter(EventKind internalEventKind, RequestId requestId, SuspendPolicy suspendPolicy, IEnumerable <EventRequestModifier> modifiers, ThreadId thread, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, StepSize size, StepDepth depth) : base(internalEventKind, requestId, suspendPolicy, modifiers, thread) { if (size == StepSize.Statement && JavaVM.DisableStatementStepping) { size = StepSize.Line; } _size = size; _depth = depth; // gather reference information for the thread using (var threadHandle = environment.VirtualMachine.GetLocalReferenceForThread(nativeEnvironment, thread)) { if (threadHandle.IsAlive) { jvmtiError error = environment.GetFrameLocation(threadHandle.Value, 0, out _lastMethod, out _lastLocation); if (error == jvmtiError.None) { error = environment.GetFrameCount(threadHandle.Value, out _stackDepth); } if (error == jvmtiError.None) { _hasMethodInfo = true; } UpdateLastLine(environment); if (error == jvmtiError.None && size == StepSize.Statement && (depth == StepDepth.Over || depth == StepDepth.Into)) { byte[] bytecode; JvmtiErrorHandler.ThrowOnFailure(environment.GetBytecodes(_lastMethod, out bytecode)); _disassembledMethod = BytecodeDisassembler.Disassemble(bytecode); TaggedReferenceTypeId declaringClass; JvmtiErrorHandler.ThrowOnFailure(environment.GetMethodDeclaringClass(nativeEnvironment, _lastMethod, out declaringClass)); using (var classHandle = environment.VirtualMachine.GetLocalReferenceForClass(nativeEnvironment, declaringClass.TypeId)) { int constantPoolCount; byte[] data; JvmtiErrorHandler.ThrowOnFailure(environment.GetConstantPool(classHandle.Value, out constantPoolCount, out data)); List <ConstantPoolEntry> entryList = new List <ConstantPoolEntry>(); int currentPosition = 0; for (int i = 0; i < constantPoolCount - 1; i++) { entryList.Add(ConstantPoolEntry.FromBytes(data, ref currentPosition)); switch (entryList.Last().Type) { case ConstantType.Double: case ConstantType.Long: // these entries take 2 slots entryList.Add(ConstantPoolEntry.Reserved); i++; break; default: break; } } _constantPool = entryList.AsReadOnly(); string classSignature; string classGenericSignature; JvmtiErrorHandler.ThrowOnFailure(environment.GetClassSignature(classHandle.Value, out classSignature, out classGenericSignature)); string methodName; string methodSignature; string methodGenericSignature; JvmtiErrorHandler.ThrowOnFailure(environment.GetMethodName(_lastMethod, out methodName, out methodSignature, out methodGenericSignature)); jobject classLoader; JvmtiErrorHandler.ThrowOnFailure(environment.GetClassLoader(classHandle.Value, out classLoader)); long classLoaderTag; JvmtiErrorHandler.ThrowOnFailure(environment.TagClassLoader(classLoader, out classLoaderTag)); ReadOnlyCollection <ExceptionTableEntry> exceptionTable; JvmtiErrorHandler.ThrowOnFailure(environment.VirtualMachine.GetExceptionTable(classLoaderTag, classSignature, methodName, methodSignature, out exceptionTable)); _evaluationStackDepths = BytecodeDisassembler.GetEvaluationStackDepths(_disassembledMethod, _constantPool, exceptionTable); } } } } }