예제 #1
0
        /// <summary>Remaps the specified line number, if a remapping has been created that applies to it.</summary>
        /// <param name="line">On entry, a real line number. On exit, a remapped line number</param>
        /// <param name="fileName">This is changed to the user-specified file name
        /// string, if and only if a file-name remapping exists and applies here.</param>
        /// <returns>true if a remapping exists and was applied, false if not.</returns>
        public bool Remap(ref int line, ref string fileName)
        {
            int i = _map.FindUpperBound(line) - 1;

            if (i == -1)
            {
                return(false);
            }
            var kvp = ((AListBase <int, KeyValuePair <int, Pair <int, string> > >)_map)[i];

            if (kvp.Value.B != null)
            {
                fileName = kvp.Value.B;
            }
            else if (kvp.Key == kvp.Value.A)
            {
                return(false);                // remap ended
            }
            int realLine   = kvp.Key;
            int reportLine = kvp.Value.A;

            Debug.Assert(line >= realLine);
            line = reportLine + (line - realLine);
            return(true);
        }
예제 #2
0
        public static TextPositionTuple GetTextPositionOfFrame(PathConverter converter, IDebugStackFrame2 frame)
        {
            IDebugDocumentContext2 documentContext;
            var source = new Source();

            if (frame.GetDocumentContext(out documentContext) == 0 &&
                documentContext != null)
            {
                var beginPosition = new TEXT_POSITION[1];
                var endPosition   = new TEXT_POSITION[1];
                documentContext.GetStatementRange(beginPosition, endPosition);

                string filePath;
                documentContext.GetName(enum_GETNAME_TYPE.GN_FILENAME, out filePath);

                string convertedFilePath = converter.ConvertDebuggerPathToClient(filePath);
                // save the filename as we need it in any case
                source.Name = Path.GetFileName(convertedFilePath);

                // we have debug info but do we actually have the source code?
                if (File.Exists(convertedFilePath))
                {
                    source.Path = convertedFilePath;
                    int srcline   = converter.ConvertDebuggerLineToClient((int)beginPosition[0].dwLine);
                    int srccolumn = unchecked ((int)(beginPosition[0].dwColumn + 1));

                    return(new TextPositionTuple(source, srcline, srccolumn));
                }
            }

            // this frame is lacking source code
            source.Name   = Path.ChangeExtension(source.Name, ".s") ?? "???";
            source.Path   = null;
            source.Origin = "disassembly";
            ulong startAddress;

            IDebugCodeContext2 codeContext;

            if (frame.GetCodeContext(out codeContext) != HRConstants.S_OK)
            {
                return(null); // we couldn't even find the current instruction, something's really wrong
            }
            var cinfos = new CONTEXT_INFO[1];

            codeContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ALLFIELDS, cinfos);

            DisassembledRange disRange;

            startAddress = (ulong)Convert.ToInt64(cinfos[0].bstrAddress, 16);

            int  idx     = DisasmRangesDict.FindUpperBound(startAddress);
            bool foundIt = false;
            int  column  = 0;
            int  line    = 0;

            if (idx > 0)
            {
                var kv = DisasmRangesDict.TryGet(idx - 1).Value;
                if (startAddress >= kv.Key && startAddress <= kv.Value.endAddress)
                {
                    disRange = kv.Value;
                    source.SourceReference = disRange.sourceReference;
                    line = kv.Value.dasmData.FirstIndexWhere(d => (ulong)Convert.ToInt64(d.bstrAddress, 16) >= startAddress) ?? 0;
                    ++line;
                    column  = 0;
                    foundIt = true;
                }
            }

            if (!foundIt)
            {
                IDebugThread2 thread;
                frame.GetThread(out thread);
                IDebugProgram2 program;
                thread.GetProgram(out program);
                IDebugDisassemblyStream2 disasmStream;
                program.GetDisassemblyStream(enum_DISASSEMBLY_STREAM_SCOPE.DSS_FUNCTION, codeContext, out disasmStream);
                uint instructionsRead;
                var  dasmData = new DisassemblyData[100];
                if (disasmStream.Read(100, enum_DISASSEMBLY_STREAM_FIELDS.DSF_ALL, out instructionsRead, dasmData) == HRConstants.S_OK)
                {
                    System.Array.Resize(ref dasmData, (int)instructionsRead);
                    source.SourceReference = ++lastSourceReference;
                    DisasmRangesDict.Add(startAddress, new DisassembledRange()
                    {
                        sourceReference = lastSourceReference,
                        endAddress      = (ulong)Convert.ToInt64(dasmData.Last().bstrAddress, 16),
                        dasmData        = dasmData
                    });
                    line   = 1;
                    column = 0;
                }
            }

            return(new TextPositionTuple(source, line, column));
        }