/// <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;
        }
Beispiel #3
0
 /// <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;
        }
Beispiel #9
0
        /// <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);
 }