public MethodDebugInfo(MethodBody body, ISymbolMethod pdb)
        {
            Body = body;

            // todo. support multiple locals sharing the same local slot
            // (but having different Start::End offsets, of course)
            // so far we just silently ignore them taking into account only the first one
            var locals = pdb.RootScope.Flatten(ss => ss.GetChildren()).SelectMany(ss => ss.GetLocals());

            LocalNames = locals.Select(lv => new { Index = lv.AddressField1, Name = lv.Name })
                         .Distinct().ToDictionary(lv => lv.Index, lv => lv.Name).ToReadOnly();

            var count      = pdb.SequencePointCount;
            var offsets    = new int[count];
            var documents  = new ISymbolDocument[count];
            var lines      = new int[count];
            var columns    = new int[count];
            var endLines   = new int[count];
            var endColumns = new int[count];

            pdb.GetSequencePoints(offsets, documents, lines, columns, endLines, endColumns);

            SequencePoints = 0.UpTo(count - 1).Select(i =>
                                                      new SequencePoint(offsets[i], documents[i], lines[i], columns[i], endLines[i], endColumns[i])
                                                      ).ToReadOnly();
        }
Beispiel #2
0
        void AddSequencePoints(CilBody body, ISymbolMethod method)
        {
            int numSeqs    = method.SequencePointCount;
            var offsets    = new int[numSeqs];
            var documents  = new ISymbolDocument[numSeqs];
            var lines      = new int[numSeqs];
            var columns    = new int[numSeqs];
            var endLines   = new int[numSeqs];
            var endColumns = new int[numSeqs];

            method.GetSequencePoints(offsets, documents, lines, columns, endLines, endColumns);

            int instrIndex = 0;

            for (int i = 0; i < numSeqs; i++)
            {
                var instr = GetInstruction(body.Instructions, offsets[i], ref instrIndex);
                if (instr == null)
                {
                    continue;
                }
                var seqPoint = new SequencePoint()
                {
                    Document    = Add_NoLock(new PdbDocument(documents[i])),
                    StartLine   = lines[i],
                    StartColumn = columns[i],
                    EndLine     = endLines[i],
                    EndColumn   = endColumns[i],
                };
                instr.SequencePoint = seqPoint;
            }
        }
Beispiel #3
0
    public LocalVariableNameReader(MethodInfo m)
    {
        ISymbolReader symReader = SymUtil.GetSymbolReaderForFile(m.DeclaringType.Assembly.Location, null);
        ISymbolMethod met       = symReader.GetMethod(new SymbolToken(m.MetadataToken));

        VisitLocals(met.RootScope);
    }
Beispiel #4
0
        //private string[] GetCombinedSource(IEnumerable<SequencePoint> points) {
        //    var lines = new List<string>();
        //    foreach (var point in points) {
        //        var contentLines = documentCache.Get(point.Document, () => File.ReadAllLines(point.Document.URL));
        //        var start = point.Start.Row - 1;
        //        var end = point.End.Row - 1;

        //        if (start >= contentLines.Length || end >= contentLines.Length)
        //            continue;

        //        for (var i = start; i <= end; i++) {
        //            var line = contentLines[i];

        //            if (i == start)
        //                line = line.Substring(point.Start.Column - 1);
        //            else if (i == end)
        //                line = line.Substring(0, point.End.Column - 1);

        //            lines.Add(line);
        //        }
        //    }

        //    return lines.ToArray();
        //}

        private IEnumerable <SequencePoint> GetSequencePoints(ISymbolMethod method)
        {
            var count = method.SequencePointCount;

            var offsets      = new int[count];
            var docs         = new ISymbolDocument[count];
            var startColumns = new int[count];
            var endColumns   = new int[count];
            var startRows    = new int[count];
            var endRows      = new int[count];

            method.GetSequencePoints(offsets, docs, startRows, startColumns, endRows, endColumns);

            for (int i = 0; i < count; i++)
            {
                if (startRows[i] == SequencePointHiddenLine || endRows[i] == SequencePointHiddenLine)
                {
                    continue;
                }

                yield return(new SequencePoint {
                    Document = this.GetOrLoadContent(docs[i]),
                    Start = new SourcePosition(startRows[i], startColumns[i]),
                    End = new SourcePosition(endRows[i], endColumns[i])
                });
            }
        }
Beispiel #5
0
        public int GetMethodVersion(ISymbolMethod method)
        {
            int version;

            unmanagedReader.GetMethodVersion(((SymbolMethod)method).InternalMethod, out version);
            return(version);
        }
Beispiel #6
0
        //�Public�Methods�(1)�

        /// <summary>
        /// Gets the method source from PDB.
        /// </summary>
        /// <param name="methodInfo">The method info.</param>
        /// <returns></returns>
        public PDBMethodSourceData GetMethodSourceFromPDB(MethodInfo methodInfo)
        {
            ISymbolMethod met = _symbolReader.GetMethod(new SymbolToken(methodInfo.MetadataToken));

            int count = met.SequencePointCount;

            ISymbolDocument[] docs       = new ISymbolDocument[count];
            int[]             offsets    = new int[count];
            int[]             lines      = new int[count];
            int[]             columns    = new int[count];
            int[]             endlines   = new int[count];
            int[]             endcolumns = new int[count];

            met.GetSequencePoints(offsets, docs, lines, columns, endlines, endcolumns);

            return(new PDBMethodSourceData()
            {
                symbolDocs = docs,
                sourceCodeLines = lines,
                ilOpcodeOffsets = offsets,
                souceCodeColumns = columns,
                sourceCodeEndColumns = endcolumns,
                sourceCodeEndLines = endlines
            });
        }
        // Write out a reference to the entry point method (if one exists)
        void WriteEntryPoint(ISymbolReader reader)
        {
            try
            {
                // If there is no entry point token (such as in a dll), this will throw.
                SymbolToken   token = reader.UserEntryPoint;
                ISymbolMethod m     = reader.GetMethod(token);

                Debug.Assert(m != null);                   // would have thrown by now.

                // Should not throw past this point
                m_writer.WriteComment(
                    "This is the token for the 'entry point' method, which is the method that will be called when the assembly is loaded." +
                    " This usually corresponds to 'Main'");

                m_writer.WriteStartElement("EntryPoint");
                WriteMethod(m);
                m_writer.WriteEndElement();
            }
            catch (System.Runtime.InteropServices.COMException)
            {
                // If the Symbol APIs fail when looking for an entry point token, there is no entry point.
                m_writer.WriteComment(
                    "There is no entry point token such as a 'Main' method. This module is probably a '.dll'");
            }
        }
        public SequencePoint[] Generate(ISymbolMethod method)
        {
            var sequencePoints = new List<SequencePoint>();
            var sp_count = method.SequencePointCount;
            var spOffsets = new int[sp_count]; // Array.CreateInstance(int, sp_count)
            var spDocs = new ISymbolDocument[sp_count]; // Array.CreateInstance(ISymbolDocument, sp_count)
            var spStartLines = new int[sp_count]; // Array.CreateInstance(int, sp_count)
            var spEndLines = new int[sp_count]; // Array.CreateInstance(int, sp_count)
            var spStartCol = new int[sp_count]; // Array.CreateInstance(int, sp_count)
            var spEndCol = new int[sp_count]; // Array.CreateInstance(int, sp_count)

            method.GetSequencePoints(spOffsets, spDocs, spStartLines, spStartCol, spEndLines, spEndCol);

            for (int i = 0; i < sp_count; i++) // (var i in range(sp_count))
            {
                if (spStartLines[i] != 0xfeefee) // if spStartLines[i] != 0xfeefee:
                {
                    sequencePoints.Add(new SequencePoint(spOffsets[i],
                                                         spDocs[i],
                                                         spStartLines[i],
                                                         spStartCol[i],
                                                         spEndLines[i],
                                                         spEndCol[i]));
                }
            }
            return sequencePoints.ToArray();
        }
Beispiel #9
0
        public int GetMethodVersion(ISymbolMethod method)
        {
            int version = 0;

            m_reader.GetMethodVersion(((SymMethod)method).InternalMethod, out version);
            return(version);
        }
Beispiel #10
0
        static void Main(string[] args)
        {
            Assembly      ass       = Assembly.GetExecutingAssembly();
            ISymbolReader symreader = SymUtil.GetSymbolReaderForFile(ass.Location, null);

            MethodInfo    m   = ass.GetType("PdbTest.TestClass").GetMethod("GetStringRepresentation");
            ISymbolMethod met = symreader.GetMethod(new SymbolToken(m.MetadataToken));

            int count = met.SequencePointCount;

            ISymbolDocument[] docs       = new ISymbolDocument[count];
            int[]             offsets    = new int[count];
            int[]             lines      = new int[count];
            int[]             columns    = new int[count];
            int[]             endlines   = new int[count];
            int[]             endcolumns = new int[count];

            met.GetSequencePoints(offsets, docs, lines, columns, endlines, endcolumns);

            StreamReader reader = new StreamReader(docs[0].URL);

            string[] linesOfCode = reader.ReadToEnd().Split('n');
            reader.Close();

            Console.WriteLine("The content of method PdbTest.TestClass.GetStringRepresentation");
            for (int i = lines[0]; i < endlines[count - 1] - 1; i++)
            {
                Console.WriteLine(linesOfCode[i]);
            }
        }
Beispiel #11
0
        // note: sadly it's not possible to cache all the [count] allocations and reuse them.
        // a NRE is throw if the size of the arrays does not match SequencePointCount :(
        void ReadSequencePoints(ISymbolMethod method, IDictionary instructions)
        {
            int count = method.SequencePointCount;

            int []             offsets     = new int [count];
            ISymbolDocument [] docs        = new ISymbolDocument [count];
            int []             startColumn = new int [count];
            int []             endColumn   = new int [count];
            int []             startRow    = new int [count];
            int []             endRow      = new int [count];
            method.GetSequencePoints(offsets, docs, startRow, startColumn, endRow, endColumn);

            for (int i = 0; i < offsets.Length; i++)
            {
                Cil.Instruction instr = (Cil.Instruction)instructions [offsets [i]];

                Cil.SequencePoint sp = new Cil.SequencePoint(GetDocument(docs [i]));
                sp.StartLine   = startRow [i];
                sp.StartColumn = startColumn [i];
                sp.EndLine     = endRow [i];
                sp.EndColumn   = endColumn [i];

                instr.SequencePoint = sp;
            }
        }
Beispiel #12
0
        // Initializes all private symbol variables
        private void SetupSymbolInformation()
        {
            if (p_symbolsInitialized)
            {
                return;
            }

            p_symbolsInitialized = true;
            CorModule     module    = GetModule();
            ISymbolReader symreader = module.GetSymbolReader();

            p_hasSymbols = symreader != null;
            if (p_hasSymbols)
            {
                ISymbolMethod sm = null;
                sm = symreader.GetMethod(new SymbolToken((Int32)GetToken())); // FIXME add version
                if (sm == null)
                {
                    p_hasSymbols = false;
                    return;
                }
                p_symMethod      = sm;
                p_SPcount        = p_symMethod.SequencePointCount;
                p_SPoffsets      = new Int32[p_SPcount];
                p_SPdocuments    = new ISymbolDocument[p_SPcount];
                p_SPstartLines   = new Int32[p_SPcount];
                p_SPendLines     = new Int32[p_SPcount];
                p_SPstartColumns = new Int32[p_SPcount];
                p_SPendColumns   = new Int32[p_SPcount];

                p_symMethod.GetSequencePoints(p_SPoffsets, p_SPdocuments, p_SPstartLines,
                                              p_SPstartColumns, p_SPendLines, p_SPendColumns);
            }
        }
Beispiel #13
0
 /// <summary>
 /// Gets information about the source if it is available.
 /// </summary>
 private bool GetSourceReference()
 {
     try
     {
         ISymbolReader sr = SymUtil.GetSymbolReaderForFile(_method.Module.Assembly.Location, null);
         ISymbolMethod sm = sr.GetMethod(new SymbolToken(_method.MetadataToken));
         _count        = sm.SequencePointCount;
         _offsets      = new int[_count];
         _documents    = new ISymbolDocument[_count];
         _startColumns = new int[_count];
         _endColumns   = new int[_count];
         _startRows    = new int[_count];
         _endRows      = new int[_count];
         sm.GetSequencePoints(_offsets, _documents, _startRows, _startColumns, _endRows, _endColumns);
         return(true);
     }
     catch
     {
         _count        = 0;
         _offsets      = null;
         _documents    = null;
         _startColumns = null;
         _endColumns   = null;
         _startRows    = null;
         _endRows      = null;
         return(false);
     }
 }
Beispiel #14
0
        private List <SymAttribute> ReadSymAttributes(ISymbolReader reader, ISymbolMethod method, bool haveCSharpCDI)
        {
            List <SymAttribute> attrs = new List <SymAttribute>();

            foreach (string name in AttributeNamesToSearch())
            {
                // If this attirubte represents C# CDI data, and we were able to expand it, then indicate that
                // the attribute here is redundant (as a raw view) and shouldn't be included again.
                if (name == k_cSharpCDIAttrName && haveCSharpCDI)
                {
                    continue;
                }

                // Note that despite being defined on ISymbolReader instead of ISymbolMethod, custom
                // attributes are permitted only on method metadata tokens.
                byte[] attrVal = reader.GetSymAttribute(method.Token, name);
                if (attrVal != null)
                {
                    SymAttribute attr = new SymAttribute();
                    attr.name  = name;
                    attr.value = Util.ToHexString(attrVal);
                    attrs.Add(attr);
                }
            }
            return(attrs);
        }
        // Write the sequence points for the given method
        // Sequence points are the map between IL offsets and source lines.
        // A single method could span multiple files (use C#'s #line directive to see for yourself).
        private SequencePoint[] ReadSequencePoints(ISymbolMethod method)
        {
            int count = method.SequencePointCount;

            // Get the sequence points from the symbol store.
            // We could cache these arrays and reuse them.
            int[]             offsets     = new int[count];
            ISymbolDocument[] docs        = new ISymbolDocument[count];
            int[]             startColumn = new int[count];
            int[]             endColumn   = new int[count];
            int[]             startRow    = new int[count];
            int[]             endRow      = new int[count];
            method.GetSequencePoints(offsets, docs, startRow, startColumn, endRow, endColumn);

            // Store them into the list
            var sequencePoints = new List <SequencePoint>(count);

            for (int i = 0; i < count; i++)
            {
                var sp = new SequencePoint(offsets[i], docs[i].URL, startRow[i], endRow[i], startColumn[i], endColumn[i]);
                sequencePoints.Add(sp);
            }

            return(sequencePoints.OrderBy(sp => sp.SourcePath).ThenBy(sp => sp.StartLine).ToArray());
        }
Beispiel #16
0
        public static IEnumerable <SequencePoint> GetSequencePoints(this ISymbolMethod met)
        {
            int sc = met.SequencePointCount;

            int[]             offsets    = new int[sc];
            int[]             lines      = new int[sc];
            int[]             endLines   = new int[sc];
            int[]             columns    = new int[sc];
            int[]             endColumns = new int[sc];
            ISymbolDocument[] docs       = new ISymbolDocument[sc];
            met.GetSequencePoints(offsets, docs, lines, columns, endLines, endColumns);

            for (int n = 0; n < sc; n++)
            {
                if (columns[n] == 0)
                {
                    continue;
                }
                SequencePoint sp = new SequencePoint();
                sp.Document = docs[n];
                sp.Line     = lines[n];
                sp.Offset   = offsets[n];
                yield return(sp);
            }
        }
Beispiel #17
0
        //////////////////////////////////////////////////////////////////////////////////
        //
        //  Initialization & locals
        //
        //////////////////////////////////////////////////////////////////////////////////

        private void EnsureIsUpToDate()
        {
            Debug.Assert(m_module != null);
            Debug.Assert(m_module.EditsCounter >= CorFunction.Version - 1);             // version cannot be greater then # of edits; versions are 1 based

            if (m_isInitialized)
            {
                return;                 // no need to do any refresh
            }
            // perform refresh
            m_isInitialized = true;
            m_haveSymbols   = m_module.SymReader != null;
            if (m_haveSymbols)
            {
                ISymbolMethod sm = null;
                sm = m_module.SymReader.GetMethod(new SymbolToken((int)m_function.Token), CorFunction.Version);
                if (sm == null)
                {
                    m_haveSymbols = false;
                    return;
                }

                m_symMethod      = sm;
                m_SPcount        = m_symMethod.SequencePointCount;
                m_SPoffsets      = new int[m_SPcount];
                m_SPdocuments    = new ISymbolDocument[m_SPcount];
                m_SPstartLines   = new int[m_SPcount];
                m_SPendLines     = new int[m_SPcount];
                m_SPstartColumns = new int[m_SPcount];
                m_SPendColumns   = new int[m_SPcount];

                m_symMethod.GetSequencePoints(m_SPoffsets, m_SPdocuments, m_SPstartLines, m_SPstartColumns, m_SPendLines, m_SPendColumns);
            }
        }
Beispiel #18
0
            /// <summary>
            /// Returns the name of the file for the given method using the given symbol reader
            /// </summary>
            /// <param name="reader">The reader to use</param>
            /// <param name="methodBase">The method to lookup</param>
            /// <returns>The file containing the method or null.</returns>
            private static string GetFileForMethod(ISymbolReader reader, MethodBase methodBase)
            {
                int token = methodBase.MetadataToken;

                ISymbolMethod methodSymbol = reader == null ? null : reader.GetMethod(new SymbolToken(token));

                if (methodSymbol != null)
                {
                    int count = methodSymbol.SequencePointCount;

                    // Get the sequence points from the symbol store.
                    // We could cache these arrays and reuse them.
                    int[]             offsets     = new int[count];
                    ISymbolDocument[] docs        = new ISymbolDocument[count];
                    int[]             startColumn = new int[count];
                    int[]             endColumn   = new int[count];
                    int[]             startRow    = new int[count];
                    int[]             endRow      = new int[count];
                    methodSymbol.GetSequencePoints(offsets, docs, startRow, startColumn, endRow, endColumn);

                    foreach (ISymbolDocument doc in docs)
                    {
                        string file = doc.URL.ToString();
                        return(file);
                    }
                }
                return(null);
            }
Beispiel #19
0
 public SymbolScope(ISymbolMethod method, ISymbolScope parent, int startOffset, int endOffset)
 {
     _children    = new List <ISymbolScope>();
     _locals      = new List <ISymbolVariable>();
     _startOffset = startOffset;
     _endOffset   = endOffset;
     _parent      = parent;
 }
Beispiel #20
0
        protected override BreakEventInfo OnInsertBreakEvent(BreakEvent be)
        {
            BreakEventInfo binfo = new BreakEventInfo();

            lock (documents) {
                Breakpoint bp = be as Breakpoint;
                if (bp != null)
                {
                    DocInfo doc;
                    if (!documents.TryGetValue(System.IO.Path.GetFullPath(bp.FileName), out doc))
                    {
                        binfo.SetStatus(BreakEventStatus.NotBound, null);
                        return(binfo);
                    }

                    int line;
                    try {
                        line = doc.Document.FindClosestLine(bp.Line);
                    }
                    catch {
                        // Invalid line
                        binfo.SetStatus(BreakEventStatus.Invalid, null);
                        return(binfo);
                    }
                    ISymbolMethod met = doc.Reader.GetMethodFromDocumentPosition(doc.Document, line, 0);
                    if (met == null)
                    {
                        binfo.SetStatus(BreakEventStatus.Invalid, null);
                        return(binfo);
                    }

                    int offset = -1;
                    foreach (SequencePoint sp in met.GetSequencePoints())
                    {
                        if (sp.Line == line && sp.Document.URL == doc.Document.URL)
                        {
                            offset = sp.Offset;
                            break;
                        }
                    }
                    if (offset == -1)
                    {
                        binfo.SetStatus(BreakEventStatus.Invalid, null);
                        return(binfo);
                    }

                    CorFunction           func  = doc.Module.GetFunctionFromToken(met.Token.GetToken());
                    CorFunctionBreakpoint corBp = func.ILCode.CreateBreakpoint(offset);
                    corBp.Activate(bp.Enabled);
                    breakpoints[corBp] = binfo;

                    binfo.Handle = corBp;
                    binfo.SetStatus(BreakEventStatus.Bound, null);
                    return(binfo);
                }
            }
            return(null);
        }
 // Write all the locals in the given method out to an XML file.
 // Since the symbol store represents the locals in a recursive scope structure, we need to walk a tree.
 // Although the locals are technically a hierarchy (based off nested scopes), it's easiest for clients
 // if we present them as a linear list. We will provide the range for each local's scope so that somebody
 // could reconstruct an approximation of the scope tree. The reconstruction may not be exact.
 // (Note this would still break down if you had an empty scope nested in another scope.
 void WriteLocals(ISymbolMethod method)
 {
     m_writer.WriteStartElement("locals");
     {
         // If there are no locals, then this element will just be empty.
         WriteLocalsHelper(method.RootScope);
     }
     m_writer.WriteEndElement();
 }
Beispiel #22
0
        public void Read(Cil.MethodBody body, IDictionary instructions)
        {
            try {
                ISymbolMethod method = m_reader.GetMethod(new SymbolToken((int)body.Method.MetadataToken.ToUInt()));

                ReadSequencePoints(method, instructions);
                ReadScopeAndLocals(method.RootScope, null, body, instructions);
            } catch (COMException) {}
        }
Beispiel #23
0
        // Dump all of the methods in the given ISymbolReader to the SymbolData provided
        private List <Method> ReadAllMethods(ISymbolReader reader)
        {
            List <Method> methods = new List <Method>();

            // Use reflection to enumerate all methods
            foreach (MethodBase methodReflection in GetAllMethods(assembly))
            {
                int           token        = methodReflection.MetadataToken;
                ISymbolMethod methodSymbol = reader.GetMethod(new SymbolToken(token));
                if (methodSymbol != null)
                {
                    Method methodData = new Method();
                    methodData.token = Util.AsToken(token);
                    methodData.name  = methodReflection.DeclaringType.FullName + "::" + methodReflection.Name;

                    // This localSigMetadataToken information actually comes from the metadata in the assembly because the symbol reading API does not provide it.
                    try
                    {
                        MethodBody body = methodReflection.GetMethodBody();
                        int        lSMT = body.LocalSignatureMetadataToken;
                        if (lSMT != 0)
                        {
                            methodData.localSigMetadataToken = Util.AsToken(lSMT);
                        }
                    }
                    catch (System.Security.VerificationException)
                    {
                        // Work around a CLR or C# compiler bug with Void& types in signatures
                        // <strip>See DevDiv Bugs 146662</strip>
                        methodData.hasInvalidMethodBody = true;
                    }

                    methodData.sequencePoints = ReadSequencePoints(methodSymbol);
                    methodData.rootScope      = ReadScope(methodSymbol.RootScope);

                    // Read symbol attributes, except on ILDB where it isn't supported
                    if (symFormat != SymbolFormat.ILDB)
                    {
                        if (expandAttributes)
                        {
                            methodData.csharpCDI = ReadCSharpCDI(reader, methodSymbol);
                        }
                        methodData.symAttributes = ReadSymAttributes(reader, methodSymbol, methodData.csharpCDI != null);
                    }

                    if (symFormat == SymbolFormat.PDB)
                    {
                        WorkAroundDiasymreaderScopeBug(methodData.rootScope);
                    }

                    methods.Add(methodData);
                }
            }

            return(methods);
        }
Beispiel #24
0
        IEnumerable <ValueReference> GetLocals(CorEvaluationContext ctx, ISymbolScope scope, int offset, bool showHidden)
        {
            if (ctx.Frame.FrameType != CorFrameType.ILFrame)
            {
                yield break;
            }

            if (scope == null)
            {
                ISymbolMethod met = ctx.Frame.Function.GetSymbolMethod(ctx.Session);
                if (met != null)
                {
                    scope = met.RootScope;
                }
                else
                {
                    int count = ctx.Frame.GetLocalVariablesCount();
                    for (int n = 0; n < count; n++)
                    {
                        int       locn = n;
                        CorValRef vref = new CorValRef(delegate {
                            return(ctx.Frame.GetLocalVariable(locn));
                        });
                        yield return(new VariableReference(ctx, vref, "local_" + (n + 1), ObjectValueFlags.Variable));
                    }
                    yield break;
                }
            }

            foreach (ISymbolVariable var in scope.GetLocals())
            {
                if (var.Name == "$site")
                {
                    continue;
                }
                if (var.Name.IndexOfAny(new char[] { '$', '<', '>' }) == -1 || showHidden)
                {
                    int       addr = var.AddressField1;
                    CorValRef vref = new CorValRef(delegate {
                        return(ctx.Frame.GetLocalVariable(addr));
                    });
                    yield return(new VariableReference(ctx, vref, var.Name, ObjectValueFlags.Variable));
                }
            }

            foreach (ISymbolScope cs in scope.GetChildren())
            {
                if (cs.StartOffset <= offset && cs.EndOffset >= offset)
                {
                    foreach (VariableReference var in GetLocals(ctx, cs, offset, showHidden))
                    {
                        yield return(var);
                    }
                }
            }
        }
	internal SymScope(ISymbolMethod method)
			{
				// Create the root scope for a method.
				this.method = method;
				this.parent = null;
				this.children = new ISymbolScope [0];
				this.locals = new ISymbolVariable [0];
				this.endOffset = Int32.MaxValue;
				this.startOffset = 0;
			}
	private SymScope(SymScope parent, int endOffset, int startOffset)
			{
				// Create a new child scope.
				this.method = parent.method;
				this.parent = parent;
				this.children = new ISymbolScope [0];
				this.locals = new ISymbolVariable [0];
				this.endOffset = endOffset;
				this.startOffset = startOffset;
			}
Beispiel #27
0
 private SymScope(SymScope parent, int endOffset, int startOffset)
 {
     // Create a new child scope.
     this.method      = parent.method;
     this.parent      = parent;
     this.children    = new ISymbolScope [0];
     this.locals      = new ISymbolVariable [0];
     this.endOffset   = endOffset;
     this.startOffset = startOffset;
 }
Beispiel #28
0
 internal SymScope(ISymbolMethod method)
 {
     // Create the root scope for a method.
     this.method      = method;
     this.parent      = null;
     this.children    = new ISymbolScope [0];
     this.locals      = new ISymbolVariable [0];
     this.endOffset   = Int32.MaxValue;
     this.startOffset = 0;
 }
Beispiel #29
0
        public void Read(Cil.MethodBody body)
        {
            try {
                ISymbolMethod method       = m_reader.GetMethod(new SymbolToken((int)body.Method.MetadataToken.ToUInt()));
                Hashtable     instructions = GetInstructions(body);

                ReadSequencePoints(method, instructions);
                ReadScopeAndLocals(method.RootScope, null, body, instructions);
            } catch {}
        }
Beispiel #30
0
            private string GetLocalVariableName(ulong instructionPointer, uint localIndex)
            {
                ClrMethod     method             = _context.Runtime.GetMethodByAddress(instructionPointer);
                ClrModule     module             = method.Type.Module;
                string        pdbLocation        = module.TryDownloadPdb(null);
                IntPtr        iunkMetadataImport = Marshal.GetIUnknownForObject(module.MetadataImport);
                ISymbolReader reader             = null;
                ISymbolMethod symMethod          = null;

                try
                {
                    using (var binder = new SymBinder())
                    {
                        reader = binder.GetReader(
                            iunkMetadataImport, module.FileName, Path.GetDirectoryName(pdbLocation));

                        symMethod = reader.GetMethod(new SymbolToken((int)method.MetadataToken));
                        return(GetLocalVariableName(symMethod.RootScope, localIndex));
                    }
                }
                catch (COMException comEx)
                {
                    // E_FAIL occasionally occurs in ISymbolReader.GetMethod. Nothing we can do about it.
                    if ((uint)comEx.HResult == 0x80004005)
                    {
                        return("");
                    }

                    // 0x806D0005 occurs when the PDB cannot be found or doesn't contain the necessary
                    // information to create a symbol reader. It's OK to ignore.
                    if ((uint)comEx.HResult == 0x806D0005)
                    {
                        return("");
                    }

                    throw;
                }
                finally
                {
                    // These interfaces aren't IDisposable, but the underlying objects are. And it is
                    // important to dispose of them properly, because if their finalizer runs on exit,
                    // it crashes with an access violation.
                    if (reader != null)
                    {
                        ((IDisposable)reader).Dispose();
                    }
                    if (symMethod != null)
                    {
                        ((IDisposable)symMethod).Dispose();
                    }

                    Marshal.Release(iunkMetadataImport);
                }
            }
Beispiel #31
0
        /// <summary>
        /// Function tries to resolve the breakpoint from breakpoint description.
        /// </summary>
        /// <param name="functionBreakpoint">A breakpoint object.</param>
        /// <param name="managedModule">A module that the breakpoint should be resolved at.</param>
        /// <param name="managedFunction">A function that is resolved from the breakpoint description.</param>
        /// <param name="ILoffset">An il offset within a function resolved from the breakpoint description.</param>
        /// <returns>true if breakpoint was successfully resolved</returns>
        /// <remarks>
        ///     Resolved is usually called for every loaded module.
        /// </remarks>
        public bool ResolveLocation(MDbgFunctionBreakpoint functionBreakpoint, MDbgModule managedModule, out List <MDbgFunction> managedFunction, out int ILoffset)
        {
            Debug.Assert(m_lineNo > 0 && m_file.Length > 0);

            managedFunction = null;
            ILoffset        = 0;

            if (managedModule.SymReader == null)
            {
                // no symbols for current module, skip it.
                return(false);
            }

            foreach (ISymbolDocument doc in managedModule.SymReader.GetDocuments())
            {
                if (String.Compare(doc.URL, m_file, true, CultureInfo.InvariantCulture) == 0 ||
                    String.Compare(System.IO.Path.GetFileName(doc.URL), m_file, true, CultureInfo.InvariantCulture) == 0)
                {
                    int lineNo = 0;
                    try
                    {
                        lineNo = doc.FindClosestLine(m_lineNo);
                    }
                    catch (System.Runtime.InteropServices.COMException e)
                    {
                        if (e.ErrorCode == (int)HResult.E_FAIL)
                        {
                            // we continue, because this location is not in this file, let's
                            // keep trying to search for next file.
                            continue;
                        }
                    }

                    ISymbolMethod symMethod = managedModule.SymReader.GetMethodFromDocumentPosition(doc, lineNo, 0);
                    managedFunction = new List <MDbgFunction>();
                    var func = managedModule.GetFunction(symMethod.Token.GetToken());
                    managedFunction.Add(func);
                    ILoffset = func.GetIPFromPosition(doc, lineNo);

                    // If this IL
                    if (ILoffset == -1)
                    {
                        return(false);
                    }
                    Debug.Assert(ILoffset != -1);
                    return(true);
                }
            }
            managedFunction = null;
            ILoffset        = -1;
            return(false);
        }
Beispiel #32
0
        public static void GetLocalVariables(Assembly asm, MethodInfo m)
        {
            // Assembly asm = Assembly.GetExecutingAssembly();
            ISymbolReader symreader = SymUtil.GetSymbolReaderForFile(asm.Location, null);

            if (symreader == null)
            {
                Console.WriteLine(" ERROR: no symreader was created. Aborting GetLocalVariables...");
                return;
            }
            ISymbolMethod symMethod = symreader.GetMethod(new SymbolToken(m.MetadataToken));

            int sequencePointCount = symMethod.SequencePointCount;

            ISymbolDocument[] docs       = new ISymbolDocument[sequencePointCount];
            int[]             offsets    = new int[sequencePointCount];
            int[]             lines      = new int[sequencePointCount];
            int[]             columns    = new int[sequencePointCount];
            int[]             endlines   = new int[sequencePointCount];
            int[]             endcolumns = new int[sequencePointCount];

            symMethod.GetSequencePoints(offsets, docs, lines, columns, endlines, endcolumns);

            Console.WriteLine();
            Console.WriteLine("The source code for method: " + m.Name + "; found in " + docs[0].URL);
            Console.WriteLine(new String('*', 60));

            // although there's an array of docs, they seem to all have the same value (?) so we'll only use the first one
            StreamReader reader = new StreamReader(docs[0].URL); // URL is typically a fully path-qualified filename

            string[] linesOfCode = reader.ReadToEnd().Split('\r');

            string PrintableLineNumber = "0000";

            Console.WriteLine(linesOfCode[lines[0] - 2].Replace('\n', ' ')); // the preceding line (assumes declaration is only one line long, and found on immediately precediting line!


            // foreach (int LineNumber in lines) // print the source code (comments omitted)
            for (int LineNumber = lines[0]; LineNumber < lines[sequencePointCount - 1] + 1; LineNumber++) // print the source code (including comments)
            {
                PrintableLineNumber = new String(' ', 4 - LineNumber.ToString().Length)                   // padding
                                      + LineNumber.ToString();
                Console.WriteLine(PrintableLineNumber + ": " + linesOfCode[LineNumber - 1].Replace('\n', ' '));
            }
            // Console.WriteLine(linesOfCode[lines[sequencePointCount -1] + 1].Replace('\n', ' ')); // the trailing line
            //Console.WriteLine(linesOfCode);
            reader.Close();

            Console.WriteLine(new String('*', 60));
            Console.WriteLine();
            linesOfCode = null;
        }
 public LocalVariableNameReader(MethodInfo m)
 {
     try
     {
         ISymbolReader symReader = SymUtil.GetSymbolReaderForFile(m.DeclaringType.Assembly.Location, null);
         ISymbolMethod met       = symReader.GetMethod(new SymbolToken(m.MetadataToken));
         VisitLocals(met.RootScope);
     }
     catch
     {
         Console.WriteLine(" ERROR: Failed LocalVariableNameReader() - perhaps this app needs to be compiled in x86?");
         return;
     }
 }
Beispiel #34
0
 private bool attemptToSetBreakpointThroughSequencePoints(ISymbolDocument doc, int line, ISymbolMethod method, CorFunction function)
 {
     bool found = false;
     foreach (var sp in getSequencePoints(method))
     {
         if (sp.Document.URL.Equals(doc.URL) && sp.LineStart.Equals(line))
         {
             var bp = function.ILCode.CreateBreakpoint(sp.Offset);
             bp.Activate(true);
             found = true;
             break;
         }
     }
     return found;
 }
        public MethodDebugInfo(MethodBody body, ISymbolMethod pdb)
        {
            Body = body;

            // todo. support multiple locals sharing the same local slot 
            // (but having different Start::End offsets, of course)
            // so far we just silently ignore them taking into account only the first one
            var locals = pdb.RootScope.Flatten(ss => ss.GetChildren()).SelectMany(ss => ss.GetLocals());
            LocalNames = locals.Select(lv => new {Index = lv.AddressField1, Name = lv.Name})
                .Distinct().ToDictionary(lv => lv.Index, lv => lv.Name).ToReadOnly();

            var count = pdb.SequencePointCount;
            var offsets = new int[count];
            var documents = new ISymbolDocument[count];
            var lines = new int[count];
            var columns = new int[count];
            var endLines = new int[count];
            var endColumns = new int[count];
            pdb.GetSequencePoints(offsets, documents, lines, columns, endLines, endColumns);

            SequencePoints = 0.UpTo(count - 1).Select(i => 
                new SequencePoint(offsets[i], documents[i], lines[i], columns[i], endLines[i], endColumns[i])
            ).ToReadOnly();
        }
Beispiel #36
0
        //private string[] GetCombinedSource(IEnumerable<SequencePoint> points) {
        //    var lines = new List<string>();
        //    foreach (var point in points) {
        //        var contentLines = documentCache.Get(point.Document, () => File.ReadAllLines(point.Document.URL));
        //        var start = point.Start.Row - 1;
        //        var end = point.End.Row - 1;
        //        if (start >= contentLines.Length || end >= contentLines.Length)
        //            continue;
        //        for (var i = start; i <= end; i++) {
        //            var line = contentLines[i];
        //            if (i == start)
        //                line = line.Substring(point.Start.Column - 1);
        //            else if (i == end)
        //                line = line.Substring(0, point.End.Column - 1);
        //            lines.Add(line);
        //        }
        //    }
        //    return lines.ToArray();
        //}
        private IEnumerable<SequencePoint> GetSequencePoints(ISymbolMethod method)
        {
            var count = method.SequencePointCount;

            var offsets = new int[count];
            var docs = new ISymbolDocument[count];
            var startColumns = new int[count];
            var endColumns = new int[count];
            var startRows = new int[count];
            var endRows = new int[count];

            method.GetSequencePoints(offsets, docs, startRows, startColumns, endRows, endColumns);

            for (int i = 0; i < count; i++) {
                if (startRows[i] == SequencePointHiddenLine || endRows[i] == SequencePointHiddenLine)
                    continue;

                yield return new SequencePoint {
                    Document = this.GetOrLoadContent(docs[i]),
                    Start = new SourcePosition(startRows[i], startColumns[i]),
                    End = new SourcePosition(endRows[i], endColumns[i])
                };
            }
        }
Beispiel #37
0
        private CSharpCDI ReadCSharpCDI(ISymbolReader reader, ISymbolMethod methodSymbol)
        {
            // See if the C# CDI attribute exists
            byte[] attrVal = reader.GetSymAttribute(methodSymbol.Token, k_cSharpCDIAttrName);
            if (attrVal == null)
                return null;        // No such attribute

            try
            {
                return CDIReader.ParseCDI(attrVal);
            }
            catch (System.FormatException e)
            {
                Console.WriteLine("WARNING: Error parsing CSharp CDI for method {0}: {1}", Util.AsToken(methodSymbol.Token.GetToken()), e.Message);
                return null;
            }
        }
Beispiel #38
0
 /// <summary>
 /// Create a new PDB method object from an ISymbolMethod object.
 /// </summary>
 /// <param name="meth">The ISymbolMethod object to wrap.</param>
 internal PDBMethod(ISymbolMethod meth)
 {
     Contract.Requires(meth != null);
     _meth = meth;
 }
        private void InitSymbolInformation()
        {
            if (p_symbolsInitialized)
                return;

            p_symbolsInitialized = true;

            ISymbolReader symreader = Module.GetSymReader();
            p_hasSymbols = symreader != null;
            if (p_hasSymbols)
            {
                ISymbolMethod sm = null;
                sm = symreader.GetMethod(new SymbolToken((Int32)Token));
                if (sm == null)
                {
                    p_hasSymbols = false;
                    return;
                }
                p_symMethod = sm;
                p_SPcount = p_symMethod.SequencePointCount;
                p_SPoffsets = new Int32[p_SPcount];
                p_SPdocuments = new ISymbolDocument[p_SPcount];
                p_SPstartLines = new Int32[p_SPcount];
                p_SPendLines = new Int32[p_SPcount];
                p_SPstartColumns = new Int32[p_SPcount];
                p_SPendColumns = new Int32[p_SPcount];

                p_symMethod.GetSequencePoints(p_SPoffsets, p_SPdocuments, p_SPstartLines,
                                                p_SPstartColumns, p_SPendLines, p_SPendColumns);
            }
        }
Beispiel #40
0
 private void Populate(ISymbolMethod method)
 {
     method.GetSequencePoints(Offsets, Documents, Lines, Columns, EndLines, EndColumns);
     for (int i = 0; i < Count; i++) {
         this.indexByOffsets.Add(Offsets[i], i);
     }
 }
Beispiel #41
0
 private SequencePoint[] getSequencePoints(ISymbolMethod method)
 {
     var factory = new SequencePointFactory();
     return factory.Generate(method);
 }
Beispiel #42
0
        // Write the sequence points for the given method
        // Sequence points are the map between IL offsets and source lines.
        // A single method could span multiple files (use C#'s #line directive to see for yourself).        
        private void WriteSequencePoints(ISymbolMethod method)
        {
            writer.WriteStartElement("sequencepoints");

            int count = method.SequencePointCount;
            writer.WriteAttributeString("total", CultureInvariantToString(count));

            // Get the sequence points from the symbol store. 
            // We could cache these arrays and reuse them.
            int[] offsets = new int[count];
            ISymbolDocument[] docs = new ISymbolDocument[count];
            int[] startColumn = new int[count];
            int[] endColumn = new int[count];
            int[] startRow = new int[count];
            int[] endRow = new int[count];
            method.GetSequencePoints(offsets, docs, startRow, startColumn, endRow, endColumn);

            // Write out sequence points
            for (int i = 0; i < count; i++)
            {
                writer.WriteStartElement("entry");
                writer.WriteAttributeString("il_offset", AsILOffset(offsets[i]));

                // If it's a special 0xFeeFee sequence point (eg, "hidden"), 
                // place an attribute on it to make it very easy for tools to recognize.
                // See http://blogs.msdn.com/jmstall/archive/2005/06/19/FeeFee_SequencePoints.aspx
                if (startRow[i] == 0xFeeFee)
                {
                    writer.WriteAttributeString("hidden", XmlConvert.ToString(true));
                }

                writer.WriteAttributeString("start_row", CultureInvariantToString(startRow[i]));
                writer.WriteAttributeString("start_column", CultureInvariantToString(startColumn[i]));
                writer.WriteAttributeString("end_row", CultureInvariantToString(endRow[i]));
                writer.WriteAttributeString("end_column", CultureInvariantToString(endColumn[i]));
                //EDMAURER allow there to be PDBs generated for sources that don't have a name (document).
                int fileRefVal = -1;
                this.m_fileMapping.TryGetValue(docs[i].URL, out fileRefVal);
                writer.WriteAttributeString("file_ref", CultureInvariantToString(fileRefVal));

                writer.WriteEndElement();
            }

            writer.WriteEndElement(); // sequencepoints
        }
Beispiel #43
0
 public int GetMethodVersion(ISymbolMethod method)
 {
     int version;
     unmanagedReader.GetMethodVersion(((SymbolMethod)method).InternalMethod, out version);
     return version;
 }
Beispiel #44
0
        // Write the sequence points for the given method
        // Sequence points are the map between IL offsets and source lines.
        // A single method could span multiple files (use C#'s #line directive to see for yourself).        
        private void WriteSequencePoints(ISymbolMethod method)
        {
            m_writer.WriteStartElement("sequencepoints");

            int count = method.SequencePointCount;
            m_writer.WriteAttributeString("total", Util.CultureInvariantToString(count));

            // Get the sequence points from the symbol store. 
            // We could cache these arrays and reuse them.
            var offsets = new int[count];
            var docs = new ISymbolDocument[count];
            var startColumn = new int[count];
            var endColumn = new int[count];
            var startRow = new int[count];
            var endRow = new int[count];
            method.GetSequencePoints(offsets, docs, startRow, startColumn, endRow, endColumn);

            // Write out sequence points
            for (int i = 0; i < count; i++)
            {
                m_writer.WriteStartElement("entry");
                m_writer.WriteAttributeString("il_offset", Util.AsIlOffset(offsets[i]));

                // If it's a special 0xFeeFee sequence point (eg, "hidden"), 
                // place an attribute on it to make it very easy for tools to recognize.
                // See http://blogs.msdn.com/jmstall/archive/2005/06/19/FeeFee_SequencePoints.aspx
                if (startRow[i] == 0xFeeFee)
                {
                    m_writer.WriteAttributeString("hidden", XmlConvert.ToString(true));
                }
                //else
                {
                    m_writer.WriteAttributeString("start_row", Util.CultureInvariantToString(startRow[i]));
                    m_writer.WriteAttributeString("start_column", Util.CultureInvariantToString(startColumn[i]));
                    m_writer.WriteAttributeString("end_row", Util.CultureInvariantToString(endRow[i]));
                    m_writer.WriteAttributeString("end_column", Util.CultureInvariantToString(endColumn[i]));
                    m_writer.WriteAttributeString("file_ref", Util.CultureInvariantToString(m_fileMapping[docs[i].URL]));
                }
                m_writer.WriteEndElement();
            }

            m_writer.WriteEndElement(); // sequencepoints
        }
Beispiel #45
0
 // Write all the locals in the given method out to an XML file.
 // Since the symbol store represents the locals in a recursive scope structure, we need to walk a tree.
 // Although the locals are technically a hierarchy (based off nested scopes), it's easiest for clients
 // if we present them as a linear list. We will provide the range for each local's scope so that somebody
 // could reconstruct an approximation of the scope tree. The reconstruction may not be exact.
 // (Note this would still break down if you had an empty scope nested in another scope.
 private void WriteLocals(ISymbolMethod method)
 {
     m_writer.WriteStartElement("locals");
     {
         // If there are no locals, then this element will just be empty.
         WriteLocalsHelper((ISymbolScope2) method.RootScope, true);
     }
     m_writer.WriteEndElement();
 }
Beispiel #46
0
        void ReadSequencePoints(ISymbolMethod method, Hashtable instructions)
        {
            int count = method.SequencePointCount;
            int [] offsets = new int [count];
            ISymbolDocument [] docs = new ISymbolDocument [count];
            int [] startColumn = new int [count];
            int [] endColumn = new int [count];
            int [] startRow = new int [count];
            int [] endRow = new int [count];
            method.GetSequencePoints (offsets, docs, startRow, startColumn, endRow, endColumn);

            for (int i = 0; i < offsets.Length; i++) {
                Cil.Instruction instr = (Cil.Instruction) instructions [offsets [i]];

                Cil.SequencePoint sp = new Cil.SequencePoint (GetDocument (docs [i]));
                sp.StartLine = startRow [i];
                sp.StartColumn = startColumn [i];
                sp.EndLine = endRow [i];
                sp.EndColumn = endColumn [i];

                instr.SequencePoint = sp;
            }
        }
Beispiel #47
0
 /// <summary>
 /// Create a new PDB method object from an ISymbolMethod object.
 /// </summary>
 /// <param name="meth">The ISymbolMethod object to wrap.</param>
 internal PDBMethod(ISymbolMethod meth)
 {
     _meth = meth;
 }
Beispiel #48
0
        // Write the sequence points for the given method
        // Sequence points are the map between IL offsets and source lines.
        // A single method could span multiple files (use C#'s #line directive to see for yourself).
        private List<SequencePoint> ReadSequencePoints(ISymbolMethod method)
        {
            int count = method.SequencePointCount;

            // Get the sequence points from the symbol store.
            // We could cache these arrays and reuse them.
            int[] offsets = new int[count];
            ISymbolDocument[] docs = new ISymbolDocument[count];
            int[] startColumn = new int[count];
            int[] endColumn = new int[count];
            int[] startRow = new int[count];
            int[] endRow = new int[count];
            method.GetSequencePoints(offsets, docs, startRow, startColumn, endRow, endColumn);

            // Store them into the list
            List<SequencePoint> sequencePoints = new List<SequencePoint>(count);
            for (int i = 0; i < count; i++)
            {
                SequencePoint sp = new SequencePoint();
                sp.ilOffset = offsets[i];

                // If it's a special 0xFeeFee sequence point (eg, "hidden"),
                // place an attribute on it to make it very easy for tools to recognize.
                // See http://blogs.msdn.com/jmstall/archive/2005/06/19/FeeFee_SequencePoints.aspx
                if (startRow[i] == 0xFeeFee)
                {
                    sp.hidden = true;
                }

                sp.sourceId = this.m_fileMapping[docs[i].URL];
                sp.startRow = startRow[i];
                sp.startColumn = startColumn[i];
                sp.endRow = endRow[i];
                sp.endColumn = endColumn[i];

                sequencePoints.Add(sp);
            }

            return sequencePoints;
        }
Beispiel #49
0
        /// <summary>
        /// Releases all resources used by the MDbgFunction.
        /// </summary>
        public void Dispose()
        {
            // Release unmanaged resources, especially symbol readers
            m_function = null;

            m_symMethod = null;
            m_SPoffsets = null;
            m_SPdocuments = null;
            m_SPstartLines = null;
            m_SPendLines = null;
            m_SPstartColumns = null;
            m_SPendColumns = null;
            m_SPcount = 0;
        }
Beispiel #50
0
        private List<SymAttribute> ReadSymAttributes(ISymbolReader reader, ISymbolMethod method, bool haveCSharpCDI)
        {
            List<SymAttribute> attrs = new List<SymAttribute>();
            foreach (string name in AttributeNamesToSearch())
            {
                // If this attirubte represents C# CDI data, and we were able to expand it, then indicate that
                // the attribute here is redundant (as a raw view) and shouldn't be included again.
                if (name == k_cSharpCDIAttrName && haveCSharpCDI)
                    continue;

                // Note that despite being defined on ISymbolReader instead of ISymbolMethod, custom
                // attributes are permitted only on method metadata tokens.
                byte[] attrVal = reader.GetSymAttribute(method.Token, name);
                if (attrVal != null)
                {
                    SymAttribute attr = new SymAttribute();
                    attr.name = name;
                    attr.value = Util.ToHexString(attrVal);
                    attrs.Add(attr);
                }
            }
            return attrs;
        }
        ISymbolDocument[] GetDocumentList(ISymbolMethod method)
        {
            int count = method.SequencePointCount;

            // Get the sequence points from the symbol store.
            // We could cache these arrays and reuse them.
            int[] offsets = new int[count];
            ISymbolDocument[] docs = new ISymbolDocument[count];
            int[] startColumn = new int[count];
            int[] endColumn = new int[count];
            int[] startRow = new int[count];
            int[] endRow = new int[count];

            method.GetSequencePoints(offsets, docs, startRow, startColumn, endRow, endColumn);
            return docs;
        }
Beispiel #52
0
 // Write out XML snippet to refer to the given method.
 private void WriteMethod(ISymbolMethod method)
 {
     m_writer.WriteElementString("methodref", Util.AsToken(method.Token.GetToken()));
 }
Beispiel #53
0
		void AddSequencePoints(CilBody body, ISymbolMethod method) {
			int numSeqs = method.SequencePointCount;
			var offsets = new int[numSeqs];
			var documents = new ISymbolDocument[numSeqs];
			var lines = new int[numSeqs];
			var columns = new int[numSeqs];
			var endLines = new int[numSeqs];
			var endColumns = new int[numSeqs];
			method.GetSequencePoints(offsets, documents, lines, columns, endLines, endColumns);

			int instrIndex = 0;
			for (int i = 0; i < numSeqs; i++) {
				var instr = GetInstruction(body.Instructions, offsets[i], ref instrIndex);
				if (instr == null)
					continue;
				var seqPoint = new SequencePoint() {
					Document = Add_NoLock(new PdbDocument(documents[i])),
					StartLine = lines[i],
					StartColumn = columns[i],
					EndLine = endLines[i],
					EndColumn = endColumns[i],
				};
				instr.SequencePoint = seqPoint;
			}
		}
Beispiel #54
0
        public ISymbolMethod[] GetMethodsFromDocumentPosition(
				ISymbolDocument document, int line, int column)
        {
            ISymUnmanagedMethod[] unmanagedMethods;
            ISymbolMethod[] methods;
            int count = 0;
            uint i;
            m_reader.GetMethodsFromDocumentPosition(((SymbolDocument)document).InternalDocument, line, column, 0, out count, null);
            unmanagedMethods = new ISymUnmanagedMethod[count];
            m_reader.GetMethodsFromDocumentPosition(((SymbolDocument)document).InternalDocument, line, column, count, out count, unmanagedMethods);
            methods = new ISymbolMethod[count];

            for (i = 0; i < count; i++)
            {
                methods[i] = new SymMethod(unmanagedMethods[i]);
            }
            return methods;
        }
Beispiel #55
0
 public int GetMethodVersion(ISymbolMethod method)
 {
     int version = 0;
     m_reader.GetMethodVersion(((SymMethod)method).InternalMethod, out version);
     return version;
 }
Beispiel #56
0
        //////////////////////////////////////////////////////////////////////////////////
        //
        //  Initialization & locals
        //
        //////////////////////////////////////////////////////////////////////////////////
        private void EnsureIsUpToDate()
        {
            Debug.Assert(m_module != null);
            Debug.Assert(m_module.EditsCounter >= CorFunction.Version - 1); // version cannot be greater then # of edits; versions are 1 based

            if (m_isInitialized)
                return; // no need to do any refresh

            // perform refresh
            m_isInitialized = true;
            m_haveSymbols = m_module.SymReader != null;
            if (m_haveSymbols)
            {
                ISymbolMethod sm = null;
                sm = m_module.SymReader.GetMethod(new SymbolToken((int)m_function.Token), CorFunction.Version);
                if (sm == null)
                {
                    m_haveSymbols = false;
                    return;
                }

                m_symMethod = sm;
                m_SPcount = m_symMethod.SequencePointCount;
                m_SPoffsets = new int[m_SPcount];
                m_SPdocuments = new ISymbolDocument[m_SPcount];
                m_SPstartLines = new int[m_SPcount];
                m_SPendLines = new int[m_SPcount];
                m_SPstartColumns = new int[m_SPcount];
                m_SPendColumns = new int[m_SPcount];

                m_symMethod.GetSequencePoints(m_SPoffsets, m_SPdocuments, m_SPstartLines, m_SPstartColumns, m_SPendLines, m_SPendColumns);
            }
        }
Beispiel #57
0
 public SequencePointCollection(ISymbolMethod method)
 {
     this.Count = method.SequencePointCount;
     this.Offsets = new int[Count];
     this.Lines = new int[Count];
     this.Columns = new int[Count];
     this.EndLines = new int[Count];
     this.EndColumns = new int[Count];
     this.Documents = new ISymbolDocument[Count];
     Populate(method);
 }
Beispiel #58
0
        // Write the sequence points for the given method
        // Sequence points are the map between IL offsets and source lines.
        // A single method could span multiple files (use C#'s #line directive to see for yourself).
        private void WriteSequencePoints(ISymbolMethod method)
        {
            int count = method.SequencePointCount;
            // Get the sequence points from the symbol store.
            // We could cache these arrays and reuse them.
            int[] offsets = new int[count];
            ISymbolDocument[] docs = new ISymbolDocument[count];
            int[] startColumn = new int[count];
            int[] endColumn = new int[count];
            int[] startRow = new int[count];
            int[] endRow = new int[count];
            method.GetSequencePoints(offsets, docs, startRow, startColumn, endRow, endColumn);

            xmlWriter.WriteStartElement("sequencePoints");
            for (int i = 0; i < count; i++)
            {
                xmlWriter.WriteStartElement("entry");
                // IL offsets are usually written in hexadecimal...
                xmlWriter.WriteAttributeString("ilOffset", "0x" + offsets[i].ToString("x4"));
                // ... but .NET XPath 1.0 cannot compare strings so we need a decimal number as well :-(
                xmlWriter.WriteAttributeString("ilOffsetDec", offsets[i].ToString());
                xmlWriter.WriteAttributeString("fileRef", fileMapping[docs[i].URL].ToString());

                // If it's a special 0xfeefee sequence point (e.g., "hidden"),
                // place an attribute on it to make it very easy for tools to recognize.
                // See http://blogs.msdn.com/b/jmstall/archive/2005/06/19/feefee-sequencepoints.aspx
                if (startRow[i] == 0xfeefee)
                {
                    xmlWriter.WriteAttributeString("hidden", "true");
                }
                else
                {
                    xmlWriter.WriteAttributeString("startLine", startRow[i].ToString());
                    xmlWriter.WriteAttributeString("startColumn", startColumn[i].ToString());
                    xmlWriter.WriteAttributeString("endLine", endRow[i].ToString());
                    xmlWriter.WriteAttributeString("endColumn", endColumn[i].ToString());
                }
                xmlWriter.WriteEndElement();   // </entry>
            }
            xmlWriter.WriteEndElement();   // </sequencePoints>
        }
Beispiel #59
0
 // Write out XML snippet to refer to the given method.
 private void WriteMethod(ISymbolMethod method)
 {
     xmlWriter.WriteElementString("methodRef", method.Token.GetToken().ToString("x8"));
 }