Beispiel #1
0
        internal Exception(Thread thread)
        {
            creationTime  = DateTime.Now;
            this.process  = thread.Process;
            this.thread   = thread;
            corValue      = thread.CorThread.CurrentException;
            exceptionType = thread.CurrentExceptionType;
            Value runtimeValue = new Value(process,
                                           new IExpirable[] { process.PauseSession },
                                           new IMutable[] {},
                                           delegate { return(corValue); });
            NamedValue nv = runtimeValue.GetMember("_message");

            if (!nv.IsNull)
            {
                message = nv.AsString;
            }
            else
            {
                message = runtimeValue.Type.FullName;
            }
            if (thread.LastFunctionWithLoadedSymbols != null)
            {
                location = thread.LastFunctionWithLoadedSymbols.NextStatement;
            }

            callstack = "";
            int callstackItems = 0;

            if (!nv.IsNull)
            {
                foreach (Function function in thread.Callstack)
                {
                    if (callstackItems >= 100)
                    {
                        callstack += "...\n";
                        break;
                    }

                    SourcecodeSegment loc = function.NextStatement;
                    callstack += function.Name + "()";
                    if (loc != null)
                    {
                        callstack += " - " + loc.SourceFullFilename + ":" + loc.StartLine + "," + loc.StartColumn;
                    }
                    callstack += "\n";
                    callstackItems++;
                }
            }

            type = runtimeValue.Type.FullName;
        }
Beispiel #2
0
        SourcecodeSegment SetIP(bool simulate, string filename, int line, int column)
        {
            process.AssertPaused();

            SourcecodeSegment suggestion = new SourcecodeSegment(filename, line, column, column);
            ICorDebugFunction corFunction;
            int ilOffset;

            if (!suggestion.GetFunctionAndOffset(this.Module, false, out corFunction, out ilOffset))
            {
                return(null);
            }
            else
            {
                if (corFunction.Token != methodProps.Token)
                {
                    return(null);
                }
                else
                {
                    try {
                        if (simulate)
                        {
                            CorILFrame.CanSetIP((uint)ilOffset);
                        }
                        else
                        {
                            // invalidates all frames and chains for the current thread
                            CorILFrame.SetIP((uint)ilOffset);
                            process.NotifyPaused(new PauseSession(PausedReason.SetIP));
                            process.Pause(false);
                        }
                    } catch {
                        return(null);
                    }
                    return(GetSegmentForOffet((uint)ilOffset));
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Returns null on error.
        ///
        /// '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>
        public SourcecodeSegment GetSegmentForOffet(uint offset)
        {
            ISymUnmanagedMethod symMethod;

            symMethod = this.symMethod;
            if (symMethod == null)
            {
                return(null);
            }

            uint sequencePointCount = symMethod.SequencePointCount;

            SequencePoint[] sequencePoints = symMethod.SequencePoints;

            SourcecodeSegment retVal = new SourcecodeSegment();

            // 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 (sequencePoints[i].Offset <= offset || i == 0)
                {
                    // Set inforamtion about current IL range
                    int codeSize = (int)corFunction.ILCode.Size;

                    retVal.ILOffset = (int)offset;
                    retVal.ILStart  = (int)sequencePoints[i].Offset;
                    retVal.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
                    int k = i;
                    // Look ahead for 'real' sequence
                    while (i + 1 < sequencePointCount && sequencePoints[i].Line == 0xFeeFee)
                    {
                        i++;
                        retVal.ILEnd = (i + 1 < sequencePointCount) ? (int)sequencePoints[i + 1].Offset : codeSize;
                    }
                    // Look back for 'real' sequence
                    while (i - 1 >= 0 && sequencePoints[i].Line == 0xFeeFee)
                    {
                        i--;
                        retVal.ILStart = (int)sequencePoints[i].Offset;
                    }
                    // Wow, there are no 'real' sequences
                    if (sequencePoints[i].Line == 0xFeeFee)
                    {
                        return(null);
                    }

                    retVal.ModuleFilename = module.FullPath;

                    retVal.SourceFullFilename = sequencePoints[i].Document.URL;

                    /*if (retVal.SourceFullFilename != null && Path.GetFileName(retVal.SourceFullFilename).StartsWith("_temp$"))
                     * {
                     *      retVal.SourceFullFilename = Path.Combine(Path.GetDirectoryName(retVal.SourceFullFilename),Path.GetFileName(retVal.SourceFullFilename).Substring(6));
                     *      System.Diagnostics.Debug.WriteLine(retVal.SourceFullFilename);
                     * }*/
                    retVal.StartLine   = (int)sequencePoints[i].Line;
                    retVal.StartColumn = (int)sequencePoints[i].Column;
                    retVal.EndLine     = (int)sequencePoints[i].EndLine;
                    retVal.EndColumn   = (int)sequencePoints[i].EndColumn;


                    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 || (j > i && (sequencePoints[j].Line == sequencePoints[i].Line && sequencePoints[i].Document.URL == sequencePoints[j].Document.URL)))                            // line + document must be same
                        // 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);
                            }
                        }
                    }


                    retVal.StepRanges = stepRanges.ToArray();

                    return(retVal);
                }
            }
            return(null);
        }