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); }
public override bool SetBreakpoint(Module module) { bool okMod = MethodKey.IsSameModule(module.FullPath); Debug.Assert(okMod, "Trying to set a BP that belongs in another module"); if (!okMod) { return(false); } SourcecodeSegment segment = SourcecodeSegment.CreateForIL(module, this.Location.Line, (int)MethodKey.Token, (int)ILOffset); if (segment == null) { return(false); } try { ICorDebugFunctionBreakpoint corBreakpoint = segment.CorFunction.GetILCode().CreateBreakpoint((uint)segment.ILStart); corBreakpoint.Activate(Enabled ? 1 : 0); corBreakpoints.Add(corBreakpoint); OnSet(new BreakpointEventArgs(this)); return(true); } catch { return(false); } }
public virtual bool SetBreakpoint(Module module) { if (this.fileName == null) { return(false); } 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); }
public static SourcecodeSegment ResolveForIL(Module module, ICorDebugFunction corFunction, int line, int offset, int[] ranges) { if (ranges == null) { return(null); // this would lead to a catched exception and the same result } try { SourcecodeSegment segment = new SourcecodeSegment(); segment.module = module; segment.typename = null; segment.checkSum = null; segment.startLine = line; segment.startColumn = 0; segment.endLine = line; segment.endColumn = 0; segment.corFunction = corFunction; segment.ilStart = offset; segment.ilEnd = ranges[1]; segment.stepRanges = ranges; return(segment); } catch { return(null); } }
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(); }
SourcecodeSegment GetSegmentForOffset(int offset) { if (SourceCodeLine != 0) { return(SourcecodeSegment.ResolveForIL(this.MethodInfo.DebugModule, corFunction, SourceCodeLine, offset, ILRanges)); } return(SourcecodeSegment.Resolve(this.MethodInfo.DebugModule, corFunction, offset)); }
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; }
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()); }
public static SourcecodeSegment CreateForIL(Module module, int line, int metadataToken, int iLOffset) { try { SourcecodeSegment segment = new SourcecodeSegment(); segment.module = module; segment.typename = null; segment.checkSum = null; segment.startLine = line; segment.startColumn = 0; segment.endLine = line; segment.endColumn = 0; segment.corFunction = module.CorModule.GetFunctionFromToken((uint)metadataToken); segment.ilStart = iLOffset; segment.ilEnd = iLOffset; segment.stepRanges = null; return(segment); } catch { return(null); } }
public override bool SetBreakpoint(Module module) { SourcecodeSegment segment = SourcecodeSegment.CreateForIL(module, this.Line, (int)MetadataToken, ILOffset); if (segment == null) { return(false); } try { ICorDebugFunctionBreakpoint corBreakpoint = segment.CorFunction.GetILCode().CreateBreakpoint((uint)segment.ILStart); corBreakpoint.Activate(Enabled ? 1 : 0); corBreakpoints.Add(corBreakpoint); OnSet(new BreakpointEventArgs(this)); return(true); } catch { return(false); } }
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; }
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)); } } }
void AsyncStep(bool stepIn) { int[] stepRanges; if (ILRanges == null) { SourcecodeSegment nextSt = NextStatement; if (nextSt == null) { throw new DebuggerException("Unable to step. Next statement not aviable"); } stepRanges = nextSt.StepRanges; } else { stepRanges = ILRanges; } if (stepIn) { Stepper stepInStepper = Stepper.StepIn(this, 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, stepRanges, "normal"); } AsyncContinue(); }
/// <summary> /// Returns null on error. /// /// 'ILStart <= ILOffset <= 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); }
internal Breakpoint(NDebugger debugger, SourcecodeSegment sourcecodeSegment, bool enabled) { this.debugger = debugger; this.sourcecodeSegment = sourcecodeSegment; this.enabled = enabled; }
SourcecodeSegment GetSegmentForOffet(int offset) { return(SourcecodeSegment.Resolve(this.MethodInfo.DebugModule, corFunction, offset)); }
public Breakpoint AddBreakpoint(SourcecodeSegment segment, bool breakpointEnabled) { return AddBreakpoint(new Breakpoint(this, segment, breakpointEnabled)); }
/// <summary> /// Returns null on error. /// /// 'ILStart <= ILOffset <= 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; }
public void StepInto() { try { workbench.WidgetController.SetStartDebugDisabled(); stepin_stmt = dbg.Processes[0].NextStatement; dbg.Processes[0].StepInto(); CurrentLineBookmark.Remove(); } catch (System.Exception e) { } }
/// <summary> /// 'ILStart <= ILOffset <= 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); }
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); }
string GetFileName(SourcecodeSegment segment) { string fileName = debuggedProcess.NextStatement.Filename; if (!Path.IsPathRooted(fileName)) { fileName = Path.Combine(debuggedProcess.WorkingDirectory, fileName); } return fileName; }
public virtual bool SetBreakpoint(Module module) { if (this.fileName == null) return false; 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; }
/// <summary> /// 'ILStart <= ILOffset <= 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; }
public static SourcecodeSegment CreateForIL(Module module, int line, int metadataToken, int iLOffset) { try { SourcecodeSegment segment = new SourcecodeSegment(); segment.module = module; segment.typename = null; segment.checkSum = null; segment.startLine = line; segment.startColumn = 0; segment.endLine = line; segment.endColumn = 0; segment.corFunction = module.CorModule.GetFunctionFromToken((uint)metadataToken); segment.ilStart = iLOffset; segment.ilEnd = iLOffset; segment.stepRanges = null; return segment; } catch { return null; } }
public static SourcecodeSegment ResolveForIL(Module module, ICorDebugFunction corFunction, int line, int offset, int[] ranges) { try { SourcecodeSegment segment = new SourcecodeSegment(); segment.module = module; segment.typename = null; segment.checkSum = null; segment.startLine = line; segment.startColumn = 0; segment.endLine = line; segment.endColumn = 0; segment.corFunction = corFunction; segment.ilStart = offset; segment.ilEnd = ranges[1]; segment.stepRanges = ranges; return segment; } catch { return null; } }
/// <summary> /// Перейти к следующей строке при отладке /// </summary> private void JumpToCurrentLine() { workbench.MainForm.Activate(); CurrentLineBookmark.Remove();//udalajem zheltyj kursor otladki //System.Threading.Thread.Sleep(70); if (debuggedProcess != null) { SourcecodeSegment nextStatement = debuggedProcess.NextStatement; //debuggedProcess.Modules[0].SymReader.GetMethod(debuggedProcess.SelectedFunction.Token); if (nextStatement != null) { string save_PrevFullFileName = PrevFullFileName; //CodeFileDocumentControl page = null; //DebuggerService.JumpToCurrentLine(nextStatement.SourceFullFilename, nextStatement.StartLine, nextStatement.StartColumn, nextStatement.EndLine, nextStatement.EndColumn); if (!show_debug_tabs)//esli eshe ne pokazany watch i lokal, pokazyvaem { show_debug_tabs = true; workbench.WidgetController.SetDebugTabsVisible(true); workbench.WidgetController.SetAddExprMenuVisible(true); } if (debuggedProcess.NextStatement.StartLine == 0xFFFFFF) { //sjuda popadem, esli vyzyvaem Test(arr), gde arr - massiv peredavaemyj po znacheniju //metod $Copy ne imeet sequence pointov, poetomu chtoby vojti v proceduru vyzovy $Copy my pomechaem 0xFFFFFFF //dolgo s etoj badjagoj muchalsja is_out = true; debuggedProcess.StepInto();//vhodim neposredstvenno v proceduru return; } else if (AssemblyHelper.IsDebuggerStepThrough(debuggedProcess.SelectedFunction)) { MustDebug = true; debuggedProcess.StepOut(); return; } else if (is_out == true) { is_out = false; if (stepin_stmt.SourceFullFilename == debuggedProcess.NextStatement.SourceFullFilename && stepin_stmt.StartLine != debuggedProcess.NextStatement.StartLine) stepin_stmt = debuggedProcess.NextStatement; else { debuggedProcess.StepInto(); return; } } if (debuggedProcess.NextStatement.SourceFullFilename != this.PrevFullFileName || !WorkbenchServiceFactory.DocumentService.ContainsTab(debuggedProcess.NextStatement.SourceFullFilename)) { tab_changed = true; curPage = WorkbenchServiceFactory.FileService.OpenFileForDebug(debuggedProcess.NextStatement.SourceFullFilename); if (curPage == null) { MustDebug = true; return; } PrevFullFileName = debuggedProcess.NextStatement.SourceFullFilename; } else if (curPage != WorkbenchServiceFactory.DocumentService.CurrentCodeFileDocument) WorkbenchServiceFactory.DocumentService.CurrentCodeFileDocument = curPage; bool remove_breakpoints = true; IDocument doc = curPage.TextEditor.Document; curTextArea = curPage.TextEditor.ActiveTextAreaControl.TextArea; LineSegment lseg = curPage.TextEditor.ActiveTextAreaControl.Document.GetLineSegment(debuggedProcess.NextStatement.StartLine - 1); int len = lseg.Length + 1; /*if (lseg.Words.Count == 1 && string.Compare(lseg.Words[0].Word,"begin",true)==0) { debuggedProcess.StepOver(); return; }*/ //eto badjaga prepjatstvuet popadaniju na begin //luchshego sposoba naverno net bool in_comm = false; bool beg = false; bool in_str = false; for (int i = 0; i < lseg.Words.Count; i++) { if (lseg.Words[i].Type == TextWordType.Word) { string word = lseg.Words[i].Word; if (string.Compare(word, "begin", true) == 0 && !in_str && !in_comm) beg = true; else if (string.Compare(word, "{") == 0) { if (!in_str) in_comm = true; } else if (string.Compare(word, "}") == 0) { if (!in_str && in_comm) in_comm = false; } else if (string.Compare(word, "'") == 0) in_str = !in_str; else if (string.Compare(word, "/") == 0) { if (i < lseg.Words.Count - 1 && string.Compare(lseg.Words[i + 1].Word, "/") == 0) break; } else if (string.Compare(word, "(") == 0) { if (i < lseg.Words.Count - 1 && string.Compare(lseg.Words[i + 1].Word, "*") == 0) { beg = false; break; } } else if (!in_str && !in_comm) { beg = false; break; } } } if (beg) { if (debuggedProcess.PausedReason != PausedReason.Exception) debuggedProcess.StepOver(); return; } if (debuggedProcess.PausedReason == PausedReason.Breakpoint) { Breakpoint br = dbg.GetBreakpoint(debuggedProcess.NextStatement.SourceFullFilename, nextStatement.StartLine); if (br != null && !BreakPointFactory.MustHit(br)) { if (Status == DebugStatus.StepOver || Status == DebugStatus.StepIn) { remove_breakpoints = false; } else { debuggedProcess.Continue(); return; } } } //for (int i=0; i<lseg.Words.Count; i++) CurrentLineBookmark.SetPosition(debuggedProcess.NextStatement.SourceFilename, curPage.TextEditor.Document, nextStatement.StartLine, 1, nextStatement.StartLine, len); curPage.TextEditor.ActiveTextAreaControl.JumpTo(nextStatement.StartLine - 1, 0); if ((Status == DebugStatus.StepOver || Status == DebugStatus.StepIn) && (CurrentLine == nextStatement.StartLine && save_PrevFullFileName == debuggedProcess.NextStatement.SourceFilename)) { if (curILOffset != nextStatement.ILOffset) { curILOffset = nextStatement.ILOffset; //debuggedProcess.StepOver(); MustDebug = true; } CurrentLine = nextStatement.StartLine; //return; } else { curILOffset = nextStatement.ILOffset; CurrentLine = nextStatement.StartLine; MustDebug = false; //MustDebug = ((nextStatement.ILOffset + 1) == nextStatement.ILEnd); } //MustDebug = false; //if (remove_breakpoints) { RemoveBreakpoints(); if (currentBreakpoint != null) { dbg.RemoveBreakpoint(currentBreakpoint); currentBreakpoint = null; //RemoveBreakpoints(); } } } } }
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); } } }
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; }
public Breakpoint AddBreakpoint(SourcecodeSegment segment, bool breakpointEnabled) { return(AddBreakpoint(new Breakpoint(this, segment, breakpointEnabled))); }