/// <summary> /// Default ctor /// </summary> public DalvikLocationBreakpoint(Jdwp.EventKind eventKind, SourceCodePosition sourcePosition, TypeEntry typeEntry, MethodEntry methodEntry) : base(eventKind) { this.typeEntry = typeEntry; this.methodEntry = methodEntry; SourceCodePosition = sourcePosition; }
/// <summary> /// Create a new location breakpoint. /// </summary> protected override DalvikLocationBreakpoint CreateLocationBreakpoint(SourceCodePosition sourceCode, TypeEntry typeEntry, MethodEntry methodEntry, object data) { // Create breakpoint objects var pendingBreakpoint = (DebugPendingBreakpoint)data; var boundBreakpoint = new DebugBoundBreakpoint<DebugLocationBreakpoint>(pendingBreakpoint, this, enum_BP_TYPE.BPT_CODE, x => new DebugLocationBreakpoint(Jdwp.EventKind.BreakPoint, sourceCode, typeEntry, methodEntry, x)); // Return breakpoint return boundBreakpoint.Breakpoint; }
/// <summary> /// Default ctor /// </summary> public DocumentLocation(Location location, SourceCodePosition sourceCode, DalvikReferenceType referenceType, DalvikMethod method, TypeEntry typeEntry, MethodEntry methodEntry) { if (location == null) throw new ArgumentNullException("location"); Location = location; SourceCode = sourceCode; ReferenceType = referenceType; Method = method; this.typeEntry = typeEntry; this.methodEntry = methodEntry; }
public int Read(uint dwInstructions, enum_DISASSEMBLY_STREAM_FIELDS dwFields, out uint pdwInstructionsRead, DisassemblyData[] prgDisassembly) { pdwInstructionsRead = 0; if (_method == null) return HResults.E_DISASM_NOTAVAILABLE; var method = _method.Method; var insCount = method.Body.Instructions.Count; bool wantsDocumentUrl = (dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL) != 0; bool wantsPosition = (dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION) != 0; bool wantsByteOffset = (dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET) != 0; bool wantsFlags = (dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS) != 0; for (pdwInstructionsRead = 0; pdwInstructionsRead < dwInstructions; ++pdwInstructionsRead, ++_instructionPointer) { int ip = _instructionPointer; if (ip >= insCount) break; var insd = new DisassemblyData(); var ins = method.Body.Instructions[ip]; if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS) != 0) { insd.bstrAddress = _method.FormatAddress(ins); insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS; } if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID) != 0) { insd.uCodeLocationId = (ulong)ins.Offset; insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID; } if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE) != 0) { insd.bstrOpcode = _method.FormatOpCode(ins); insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE; } if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS) != 0) { insd.bstrOperands = _method.FormatOperands(ins); insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS; } if (wantsDocumentUrl || wantsPosition || wantsByteOffset || wantsFlags) { var source = _method.FindSourceCode(ins.Offset); var hasSource = source != null && !source.IsSpecial; bool isSameDocAsPrevious, isSameDocPos; if (hasSource) { isSameDocAsPrevious = _prevSource != null && !_prevSource.IsSpecial && _prevSource.Document.Path == source.Document.Path; isSameDocPos = _prevSource != null && !_prevSource.IsSpecial && isSameDocAsPrevious && source.Position.CompareTo(_prevSource.Position) == 0; } else { isSameDocAsPrevious = (source == null && _prevSource == null) || (source != null && _prevSource != null && _prevSource.IsSpecial); isSameDocPos = isSameDocAsPrevious; } if (wantsDocumentUrl && (!isSameDocAsPrevious || _justSeeked)) { if (hasSource) { insd.bstrDocumentUrl = "file://" + source.Document.Path; insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL; } // how do I clear the document? } int byteOffset = 0; if ((wantsByteOffset || wantsPosition) && hasSource) { if (isSameDocPos) byteOffset = ins.Offset - _prevSourceInstructionOffset; else { byteOffset = 0; _prevSourceInstructionOffset = ins.Offset; } } if (wantsPosition && hasSource && !isSameDocPos) { var pos = source.Position; insd.posBeg.dwLine = (uint)(pos.Start.Line - 1); insd.posBeg.dwColumn = (uint)(pos.Start.Column - 1); insd.posEnd.dwLine = (uint)(pos.End.Line - 1); insd.posEnd.dwColumn = (uint)(pos.End.Column - 1); if (insd.posEnd.dwLine - insd.posBeg.dwLine > 3) // never show more than 3 lines. insd.posEnd.dwLine = insd.posBeg.dwLine + 3; // Is this just me? I have no idea why my VS throws an exception when using this. //insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION; } if (wantsByteOffset && hasSource) { insd.dwByteOffset = (uint)byteOffset; insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET; } if (wantsFlags) { if(!isSameDocAsPrevious) insd.dwFlags |= enum_DISASSEMBLY_FLAGS.DF_DOCUMENTCHANGE; if(hasSource) insd.dwFlags |= enum_DISASSEMBLY_FLAGS.DF_HASSOURCE; //if (_loc.Location.Index == (ulong)ins.Offset) // insd.dwFlags |= enum_DISASSEMBLY_FLAGS.DF_INSTRUCTION_ACTIVE; insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS; } if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS) != 0) { if (!hasSource && !isSameDocPos) { insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS; insd.bstrSymbol = "(generated instructions)"; } else if (hasSource && !isSameDocPos) { // workaround to show something at least if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS) != 0) { insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS; insd.bstrSymbol = "File Position: " + source.Position.Start + " - " + source.Position.End; } } } _justSeeked = false; _prevSource = source; } prgDisassembly[pdwInstructionsRead] = insd; } return pdwInstructionsRead == 0 || _instructionPointer >= insCount ? VSConstants.S_FALSE : VSConstants.S_OK; }
public int Seek(enum_SEEK_START dwSeekStart, IDebugCodeContext2 pCodeContext, ulong uCodeLocationId, long iInstructions) { _justSeeked = true; _prevSource = null; _prevSourceInstructionOffset = -1; if (_method == null) return HResults.E_DISASM_NOTAVAILABLE; var method = _method.Method; var insCount = method.Body.Instructions.Count; int newPos; switch (dwSeekStart) { case enum_SEEK_START.SEEK_START_BEGIN: newPos = (int)iInstructions; break; case enum_SEEK_START.SEEK_START_END: newPos = insCount + (int)iInstructions; break; case enum_SEEK_START.SEEK_START_CURRENT: newPos = _instructionPointer + (int)iInstructions; break; default: return VSConstants.E_NOTIMPL; } _instructionPointer = newPos < 0 ? 0 : newPos >= insCount ? insCount - 1 : newPos; if (newPos < 0 || newPos >= insCount) return VSConstants.S_FALSE; return VSConstants.S_OK; }
/// <summary> /// Default ctor /// </summary> public DebugLocationBreakpoint(Jdwp.EventKind eventKind, SourceCodePosition sourcePosition, TypeEntry typeEntry, MethodEntry methodEntry, BreakpointBookmark bookmark) : base(eventKind, sourcePosition, typeEntry, methodEntry) { this.bookmark = bookmark; InvalidateBookmark(); }
/// <summary> /// Default ctor /// </summary> public DebugLocationBreakpoint(Jdwp.EventKind eventKind, SourceCodePosition sourcePosition, TypeEntry typeEntry, MethodEntry methodEntry, DebugBoundBreakpoint<DebugLocationBreakpoint> boundBreakpoint) : base(eventKind, sourcePosition, typeEntry, methodEntry) { this.boundBreakpoint = boundBreakpoint; }
private string[] GetSourceCodeLines(SourceCodePosition source) { // there can be at most one document per method, so don't protect // against document path changes. var lines = _sourceDocument.Value; if (_sourceDocument.Value == null) return null; var pos = source.Position; var startLine = pos.Start.Line - 1; if (startLine >= lines.Length) return null; if (startLine < 0) return null; int numLines = pos.End.Line - startLine; if (numLines < 0) numLines = 1; if (startLine + numLines >= lines.Length) numLines = lines.Length - startLine; if (numLines > 3) // show at most 3 lines. numLines = 3; string[] ret = new string[numLines]; for (int i = 0; i < numLines; ++i) ret[i] = lines[startLine + i]; return ret; }
/// <summary> /// Get a DocumentLocation from a SourceCodePosition. This will only return locations /// for classes that have already been loaded by the VM. Delegates are typically not /// loaded until their first invocation. /// </summary> public Task<DocumentLocation> GetLocationFromPositionAsync(SourceCodePosition sourcePos) { return Task.Factory.StartNew(() => { // Lookup class & method var typeEntry = MapFile.GetTypeById(sourcePos.Position.TypeId); if (typeEntry == null) return null; var methodEntry = typeEntry.GetMethodById(sourcePos.Position.MethodId); if (methodEntry == null) return null; var signature = typeEntry.DexSignature; var refType = ReferenceTypeManager.FindBySignature(signature); if (refType == null) return null; var refTypeMethods = refType.GetMethodsAsync().Await(VmTimeout); var dmethod = refTypeMethods.FirstOrDefault(x => x.IsMatch(methodEntry)); if (dmethod == null) return null; var loc = new Location(refType.Id, dmethod.Id, (ulong)sourcePos.Position.MethodOffset); return new DocumentLocation(loc, sourcePos, refType, dmethod, typeEntry, methodEntry); }); }
/// <summary> /// Create custom breakpoint. /// </summary> protected override DalvikLocationBreakpoint CreateLocationBreakpoint(SourceCodePosition sourcePosition, TypeEntry typeEntry, MethodEntry methodEntry, object data) { return new DebugLocationBreakpoint(Jdwp.EventKind.BreakPoint, sourcePosition, typeEntry, methodEntry, (BreakpointBookmark)data); }