예제 #1
0
        private SourcecodeSegment SetIP(bool simulate, string filename, int line, int column)
        {
            process.AssertPaused();

            SourcecodeSegment segment = SourcecodeSegment.Resolve(this.MethodInfo.DebugModule, filename, null, line, column);

            if (segment != null && segment.CorFunction.GetToken() == this.MethodInfo.MetadataToken)
            {
                try
                {
                    if (simulate)
                    {
                        CorILFrame.CanSetIP((uint)segment.ILStart);
                    }
                    else
                    {
                        // Invalidates all frames and chains for the current thread
                        CorILFrame.SetIP((uint)segment.ILStart);
                        process.NotifyResumed(DebuggeeStateAction.Keep);
                        process.NotifyPaused(PausedReason.SetIP);
                        process.RaisePausedEvents();
                    }
                }
                catch
                {
                    return(null);
                }
                return(segment);
            }
            return(null);
        }
예제 #2
0
        private void AsyncStep(bool stepIn)
        {
            if (this.MethodInfo.DebugModule.HasSymbols == false)
            {
                throw new DebuggerException("Unable to step. No symbols loaded.");
            }

            SourcecodeSegment nextSt = NextStatement;

            if (nextSt == null)
            {
                throw new DebuggerException("Unable to step. Next statement not aviable");
            }

            if (stepIn)
            {
                Stepper stepInStepper = Stepper.StepIn(this, nextSt.StepRanges, "normal");
                this.Thread.CurrentStepIn = stepInStepper;
                Stepper clearCurrentStepIn = Stepper.StepOut(this, "clear current step in");
                clearCurrentStepIn.StepComplete += delegate
                {
                    if (this.Thread.CurrentStepIn == stepInStepper)
                    {
                        this.Thread.CurrentStepIn = null;
                    }
                };
                clearCurrentStepIn.Ignore = true;
            }
            else
            {
                Stepper.StepOver(this, nextSt.StepRanges, "normal");
            }

            AsyncContinue();
        }
예제 #3
0
        public string GetStackTrace(string formatSymbols, string formatNoSymbols)
        {
            StringBuilder stackTrace = new StringBuilder();

            foreach (StackFrame stackFrame in this.GetCallstack(100))
            {
                SourcecodeSegment loc = stackFrame.NextStatement;
                stackTrace.Append("   ");
                if (loc != null)
                {
                    stackTrace.AppendFormat(formatSymbols, stackFrame.MethodInfo.FullName, loc.Filename, loc.StartLine);
                }
                else
                {
                    stackTrace.AppendFormat(formatNoSymbols, stackFrame.MethodInfo.FullName);
                }
                stackTrace.AppendLine();
            }
            return(stackTrace.ToString());
        }
예제 #4
0
        internal bool SetBreakpoint(Module module)
        {
            SourcecodeSegment segment = SourcecodeSegment.Resolve(module, FileName, CheckSum, Line, Column);

            if (segment == null)
            {
                return(false);
            }

            originalLocation = segment;

            ICorDebugFunctionBreakpoint corBreakpoint = segment.CorFunction.GetILCode().CreateBreakpoint((uint)segment.ILStart);

            corBreakpoint.Activate(_enabled ? 1 : 0);

            corBreakpoints.Add(corBreakpoint);

            OnSet(new BreakpointEventArgs(this));

            return(true);
        }
예제 #5
0
        /// <summary>
        /// 'ILStart &lt;= ILOffset &lt;= ILEnd' and this range includes at least
        /// the returned area of source code. (May incude some extra compiler generated IL too)
        /// </summary>
        internal static SourcecodeSegment Resolve(Module module, ICorDebugFunction corFunction, int offset)
        {
            ISymUnmanagedReader symReader = module.SymReader;

            if (symReader == null)
            {
                return(null);                   // No symbols
            }
            ISymUnmanagedMethod symMethod;

            try
            {
                symMethod = symReader.GetMethod(corFunction.GetToken());
            }
            catch (COMException)
            {
                // Can not find the method
                // eg. Compiler generated constructors are not in symbol store
                return(null);
            }
            if (symMethod == null)
            {
                return(null);
            }

            uint sequencePointCount = symMethod.GetSequencePointCount();

            SequencePoint[] sequencePoints = symMethod.GetSequencePoints();

            // Get i for which: offsets[i] <= offset < offsets[i + 1]
            // or fallback to first element if  offset < offsets[0]
            for (int i = (int)sequencePointCount - 1; i >= 0; i--)
            { // backwards
                if ((int)sequencePoints[i].Offset <= offset || i == 0)
                {
                    // Set inforamtion about current IL range
                    int codeSize = (int)corFunction.GetILCode().GetSize();

                    int ilStart = (int)sequencePoints[i].Offset;
                    int ilEnd   = (i + 1 < sequencePointCount) ? (int)sequencePoints[i + 1].Offset : codeSize;

                    // 0xFeeFee means "code generated by compiler"
                    // If we are in generated sequence use to closest real one instead,
                    // extend the ILStart and ILEnd to include the 'real' sequence

                    // Look ahead for 'real' sequence
                    while (i + 1 < sequencePointCount && sequencePoints[i].Line == 0xFeeFee)
                    {
                        i++;
                        ilEnd = (i + 1 < sequencePointCount) ? (int)sequencePoints[i + 1].Offset : codeSize;
                    }
                    // Look back for 'real' sequence
                    while (i - 1 >= 0 && sequencePoints[i].Line == 0xFeeFee)
                    {
                        i--;
                        ilStart = (int)sequencePoints[i].Offset;
                    }
                    // Wow, there are no 'real' sequences
                    if (sequencePoints[i].Line == 0xFeeFee)
                    {
                        return(null);
                    }

                    List <int> stepRanges = new List <int>();
                    for (int j = 0; j < sequencePointCount; j++)
                    {
                        // Step over compiler generated sequences and current statement
                        // 0xFeeFee means "code generated by compiler"
                        if (sequencePoints[j].Line == 0xFeeFee || j == i)
                        {
                            // Add start offset or remove last end (to connect two ranges into one)
                            if (stepRanges.Count > 0 && stepRanges[stepRanges.Count - 1] == sequencePoints[j].Offset)
                            {
                                stepRanges.RemoveAt(stepRanges.Count - 1);
                            }
                            else
                            {
                                stepRanges.Add((int)sequencePoints[j].Offset);
                            }
                            // Add end offset | handle last sequence point
                            if (j + 1 < sequencePointCount)
                            {
                                stepRanges.Add((int)sequencePoints[j + 1].Offset);
                            }
                            else
                            {
                                stepRanges.Add(codeSize);
                            }
                        }
                    }

                    SourcecodeSegment segment = new SourcecodeSegment();
                    segment.module      = module;
                    segment.filename    = GetFilenameFromSymDocument(module, sequencePoints[i].Document);
                    segment.checkSum    = sequencePoints[i].Document.GetCheckSum();
                    segment.startLine   = (int)sequencePoints[i].Line;
                    segment.startColumn = (int)sequencePoints[i].Column;
                    segment.endLine     = (int)sequencePoints[i].EndLine;
                    segment.endColumn   = (int)sequencePoints[i].EndColumn;
                    segment.corFunction = corFunction;
                    segment.ilStart     = ilStart;
                    segment.ilEnd       = ilEnd;
                    segment.stepRanges  = stepRanges.ToArray();

                    // VB.NET sometimes produces temporary files which it then deletes
                    // (eg 17d14f5c-a337-4978-8281-53493378c1071.vb)
                    string filename = Path.GetFileName(segment.filename);
                    if (filename.Length == 40 && filename.EndsWith(".vb"))
                    {
                        bool guidName = true;
                        foreach (char c in filename.Substring(0, filename.Length - 3))
                        {
                            if (('0' <= c && c <= '9') ||
                                ('a' <= c && c <= 'f') ||
                                ('A' <= c && c <= 'F') ||
                                (c == '-'))
                            {
                                guidName = true;
                            }
                            else
                            {
                                guidName = false;
                                break;
                            }
                        }
                        if (guidName)
                        {
                            return(null);
                        }
                    }

                    return(segment);
                }
            }
            return(null);
        }
예제 #6
0
        public static SourcecodeSegment Resolve(Module module, string fileName, byte[] checkSum, int line, int column)
        {
            // Do not use ISymUnmanagedReader.GetDocument!  It is broken if two files have the same name
            // Do not use ISymUnmanagedMethod.GetOffset!  It sometimes returns negative offset

            ISymUnmanagedReader symReader = module.SymReader;

            if (symReader == null)
            {
                return(null);                   // No symbols
            }
            ISymUnmanagedDocument symDoc = GetSymDocumentFromFilename(module, fileName, checkSum);

            if (symDoc == null)
            {
                return(null);                // Document not found
            }
            ISymUnmanagedMethod symMethod;

            try
            {
                uint validLine = symDoc.FindClosestLine((uint)line);
                symMethod = symReader.GetMethodFromDocumentPosition(symDoc, (uint)validLine, (uint)column);
            }
            catch
            {
                return(null); //Not found
            }

            SequencePoint[] seqPoints = symMethod.GetSequencePoints();
            Array.Sort(seqPoints);
            if (seqPoints.Length == 0)
            {
                return(null);
            }
            if (line < seqPoints[0].Line)
            {
                return(null);
            }
            foreach (SequencePoint sqPoint in seqPoints)
            {
                if (sqPoint.Line == 0xFEEFEE)
                {
                    continue;
                }
                // If the desired breakpoint position is before the end of the sequence point
                if (line < sqPoint.EndLine || (line == sqPoint.EndLine && column < sqPoint.EndColumn))
                {
                    SourcecodeSegment segment = new SourcecodeSegment();
                    segment.module      = module;
                    segment.filename    = symDoc.GetURL();
                    segment.checkSum    = symDoc.GetCheckSum();
                    segment.startLine   = (int)sqPoint.Line;
                    segment.startColumn = (int)sqPoint.Column;
                    segment.endLine     = (int)sqPoint.EndLine;
                    segment.endColumn   = (int)sqPoint.EndColumn;
                    segment.corFunction = module.CorModule.GetFunctionFromToken(symMethod.GetToken());
                    segment.ilStart     = (int)sqPoint.Offset;
                    segment.ilEnd       = (int)sqPoint.Offset;
                    segment.stepRanges  = null;
                    return(segment);
                }
            }
            return(null);
        }
예제 #7
0
 private SourcecodeSegment GetSegmentForOffet(int offset)
 {
     return(SourcecodeSegment.Resolve(this.MethodInfo.DebugModule, corFunction, offset));
 }