void SetBreakEventHandle(BreakEvent be, object handle) { lock (breakpoints) { BreakEventInfo bi; if (!breakpoints.TryGetValue(be, out bi)) { bi = new BreakEventInfo(handle); } else { bi.Handle = handle; } breakpoints [be] = bi; } }
/// <summary> /// This method can be used by subclasses to set the validity of a breakpoint. /// </summary> protected void SetBreakEventStatus(BreakEvent be, bool isValid) { lock (breakpoints) { BreakEventInfo bi; if (!breakpoints.TryGetValue(be, out bi)) { bi = new BreakEventInfo(null); } if (bi.IsValid != isValid) { bi.IsValid = isValid; breakpoints [be] = bi; Breakpoints.NotifyStatusChanged(be); } } }
protected override void OnEnableBreakEvent (BreakEventInfo binfo, bool enable) { if (exited) return; var bi = (BreakInfo) binfo; if (bi.Requests.Count != 0) { foreach (var request in bi.Requests) request.Enabled = enable; if (!enable) RemoveQueuedBreakEvents (bi.Requests); } }
/// <summary> /// Called when a break event is enabled or disabled /// </summary> /// <param name='eventInfo'> /// The break event /// </param> /// <param name='enable'> /// The new status /// </param> protected abstract void OnEnableBreakEvent (BreakEventInfo eventInfo, bool enable);
/// <summary> /// Called when a breakpoint has been removed. /// </summary> /// <param name='eventInfo'> /// The breakpoint /// </param> /// <remarks> /// Implementations of this method should remove or disable the breakpoint /// in the debugging engine. /// </remarks> protected abstract void OnRemoveBreakEvent (BreakEventInfo eventInfo);
protected override void OnEnableBreakEvent (BreakEventInfo binfo, bool enable) { if (exited) return; BreakInfo bi = (BreakInfo) binfo; if (bi.Req != null) { bi.Req.Enabled = enable; if (!enable) RemoveQueuedBreakEvents (bi.Req); } }
protected override void OnRemoveBreakEvent (BreakEventInfo bi) { if (terminated) return; if (bi.Status != BreakEventStatus.Bound || bi.Handle == null) return; CorFunctionBreakpoint corBp = (CorFunctionBreakpoint)bi.Handle; corBp.Activate (false); }
protected override void OnEnableBreakEvent (BreakEventInfo binfo, bool enable) { CorBreakpoint bp = binfo.Handle as CorFunctionBreakpoint; if (bp != null) bp.Activate (enable); }
void NotifyBreakEventUpdate (BreakEventInfo binfo, int hitCount, string lastTrace) { bool notify = false; WaitCallback nc = delegate { if (hitCount != -1) binfo.UpdateHitCount (hitCount); if (lastTrace != null) binfo.UpdateLastTraceValue (lastTrace); }; lock (breakUpdates) { int span = (int) (DateTime.Now - lastBreakEventUpdate).TotalMilliseconds; if (span >= BreakEventUpdateNotifyDelay && !breakUpdateEventsQueued) { // Last update was more than 0.5s ago. The update can be sent. lastBreakEventUpdate = DateTime.Now; notify = true; } else { // Queue the event notifications to avoid wasting too much time breakUpdates [(int)binfo.Handle] = nc; if (!breakUpdateEventsQueued) { breakUpdateEventsQueued = true; ThreadPool.QueueUserWorkItem (delegate { Thread.Sleep (BreakEventUpdateNotifyDelay - span); List<WaitCallback> copy; lock (breakUpdates) { copy = new List<WaitCallback> (breakUpdates.Values); breakUpdates.Clear (); breakUpdateEventsQueued = false; lastBreakEventUpdate = DateTime.Now; } foreach (WaitCallback wc in copy) wc (null); }); } } } if (notify) nc (null); }
protected override BreakEventInfo OnInsertBreakEvent (BreakEvent be) { Breakpoint bp = be as Breakpoint; if (bp == null) throw new NotSupportedException (); BreakEventInfo bi = new BreakEventInfo (); lock (gdbLock) { bool dres = InternalStop (); try { string extraCmd = string.Empty; if (bp.HitCount > 0) { extraCmd += "-i " + bp.HitCount; breakpointsWithHitCount.Add (bi); } if (!string.IsNullOrEmpty (bp.ConditionExpression)) { if (!bp.BreakIfConditionChanges) extraCmd += " -c " + bp.ConditionExpression; } GdbCommandResult res = null; string errorMsg = null; if (bp is FunctionBreakpoint) { try { res = RunCommand ("-break-insert", extraCmd.Trim (), ((FunctionBreakpoint) bp).FunctionName); } catch (Exception ex) { errorMsg = ex.Message; } } else { // Breakpoint locations must be double-quoted if files contain spaces. // For example: -break-insert "\"C:/Documents and Settings/foo.c\":17" RunCommand ("-environment-directory", Escape (Path.GetDirectoryName (bp.FileName))); try { res = RunCommand ("-break-insert", extraCmd.Trim (), Escape (Escape (bp.FileName) + ":" + bp.Line)); } catch (Exception ex) { errorMsg = ex.Message; } if (res == null) { try { res = RunCommand ("-break-insert", extraCmd.Trim (), Escape (Escape (Path.GetFileName (bp.FileName)) + ":" + bp.Line)); } catch { // Ignore } } } if (res == null) { bi.SetStatus (BreakEventStatus.Invalid, errorMsg); return bi; } int bh = res.GetObject ("bkpt").GetInt ("number"); if (!be.Enabled) RunCommand ("-break-disable", bh.ToString ()); breakpoints [bh] = bi; bi.Handle = bh; bi.SetStatus (BreakEventStatus.Bound, null); return bi; } finally { InternalResume (dres); } } }
void FireBreakPoint(ulong offset) { TargetEventArgs args = new TargetEventArgs(TargetEventType.TargetHitBreakpoint); ulong tempoff = (ulong)offset; if (breakpoints.ContainsKey(tempoff)) { breakpoints[(ulong)tempoff].EventInfo.UpdateHitCount((int)breakpoints[(ulong)tempoff].Breakpoint.HitCount); args.BreakEvent = breakpoints[(ulong)tempoff].EventInfo.BreakEvent; } else { args = new TargetEventArgs(TargetEventType.TargetStopped); BreakEventInfo breakInfo = new BreakEventInfo(); breakInfo.Handle = tempoff; breakInfo.SetStatus (BreakEventStatus.Bound, null); string fn; uint ln; if (Engine.Symbols.GetLineByOffset(offset, out fn, out ln)) { //breakInfo.BreakEvent = new Breakpoint(fn, (int)ln); args.BreakEvent = breakInfo.BreakEvent; } } ProcessInfo process = OnGetProcesses()[0]; args.Process = new ProcessInfo(process.Id, process.Name); args.Backtrace = new Backtrace(new DDebugBacktrace(this, activeThread, Engine)); ThreadPool.QueueUserWorkItem(delegate(object data) { try { OnTargetEvent((TargetEventArgs)data); } catch (Exception ex) { Console.WriteLine(ex); } }, args); }
protected override void OnRemoveBreakEvent(BreakEventInfo binfo) { if (binfo == null) return; breakpointsWithHitCount.Remove (binfo); DebugEngineWrapper.BreakPoint breakpoint = breakpoints[(ulong)binfo.Handle].Breakpoint; if (IsDebugging /*&& bpw.IsExisting*/) Engine.RemoveBreakPoint(breakpoint); breakpointsWithHitCount.Remove (binfo); breakpoints.Remove((ulong)binfo.Handle); }
protected override BreakEventInfo OnInsertBreakEvent(BreakEvent be) { Breakpoint bp = be as Breakpoint; if (bp == null) throw new NotSupportedException (); BreakEventInfo breakEventInfo = new BreakEventInfo (); //bool dres = InternalStop (); try { string extraCmd = string.Empty; if (bp.HitCount > 0) { extraCmd += "-i " + bp.HitCount; breakpointsWithHitCount.Add (breakEventInfo); } if (!string.IsNullOrEmpty (bp.ConditionExpression)) { if (!bp.BreakIfConditionChanges) extraCmd += " -c " + bp.ConditionExpression; } ulong bh = 0; DebugEngineWrapper.BreakPoint engineBreakPoint = null; ulong off = 0; if (Engine.Symbols.GetOffsetByLine(bp.FileName, (uint)bp.Line, out off)) { engineBreakPoint = Engine.AddBreakPoint(BreakPointOptions.Enabled); engineBreakPoint.Offset = off; bh = engineBreakPoint.Offset; breakpoints[bh] = new BreakPointWrapper(breakEventInfo, engineBreakPoint); breakEventInfo.Handle = bh; breakEventInfo.SetStatus(BreakEventStatus.Bound, null); //if (!be.Enabled) //ToDo: tell debugger engine that breakpoint is disabled } else { breakEventInfo.SetStatus(BreakEventStatus.BindError, null); } return breakEventInfo; } finally { //InternalResume (dres); } }
public BreakPointWrapper(BreakEventInfo eventInfo, DebugEngineWrapper.BreakPoint breakpoint) { EventInfo = eventInfo; Breakpoint = breakpoint; }
protected override void OnEnableBreakEvent(BreakEventInfo binfo, bool enable) { if (binfo.Handle == null) return; breakpoints[(ulong)binfo.Handle].Breakpoint.Flags = enable? BreakPointOptions.Enabled : BreakPointOptions.Deferred; //ToDo: tell engine we enabled a break point }
protected override void OnEnableBreakEvent (BreakEventInfo eventInfo, bool enable) { throw new NotImplementedException (); }
protected override void OnUpdateBreakEvent(BreakEventInfo binfo) { LogWriter(false, "Break updated " + binfo.ToString()); }
protected override void OnRemoveBreakEvent (BreakEventInfo binfo) { lock (gdbLock) { if (binfo.Handle == null) return; bool dres = InternalStop (); breakpointsWithHitCount.Remove (binfo); breakpoints.Remove ((int)binfo.Handle); try { RunCommand ("-break-delete", binfo.Handle.ToString ()); } finally { InternalResume (dres); } } }
protected override BreakEventInfo OnInsertBreakEvent (BreakEvent be) { BreakEventInfo binfo = new BreakEventInfo (); lock (documents) { Breakpoint bp = be as Breakpoint; if (bp != null) { if (bp is FunctionBreakpoint) { // FIXME: implement breaking on function name binfo.SetStatus (BreakEventStatus.Invalid, null); return binfo; } else { 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; }
protected override void OnEnableBreakEvent (BreakEventInfo binfo, bool enable) { lock (gdbLock) { if (binfo.Handle == null) return; bool dres = InternalStop (); try { if (enable) RunCommand ("-break-enable", binfo.Handle.ToString ()); else RunCommand ("-break-disable", binfo.Handle.ToString ()); } finally { InternalResume (dres); } } }
protected override void OnRemoveBreakEvent (BreakEventInfo binfo) { if (exited) return; BreakInfo bi = (BreakInfo) binfo; if (bi.Req != null) { bi.Req.Enabled = false; RemoveQueuedBreakEvents (bi.Req); } pending_bes.Remove (bi); }
protected override void OnUpdateBreakEvent (BreakEventInfo binfo) { Breakpoint bp = binfo.BreakEvent as Breakpoint; if (bp == null) throw new NotSupportedException (); if (binfo.Handle == null) return; bool ss = InternalStop (); try { if (bp.HitCount > 0) { RunCommand ("-break-after", binfo.Handle.ToString (), bp.HitCount.ToString ()); breakpointsWithHitCount.Add (binfo); } else breakpointsWithHitCount.Remove (binfo); if (!string.IsNullOrEmpty (bp.ConditionExpression) && !bp.BreakIfConditionChanges) RunCommand ("-break-condition", binfo.Handle.ToString (), bp.ConditionExpression); else RunCommand ("-break-condition", binfo.Handle.ToString ()); } finally { InternalResume (ss); } }
void RetryEventBind (BreakEventInfo binfo) { // Try inserting the breakpoint again BreakEvent be = binfo.BreakEvent; try { binfo = OnInsertBreakEvent (be); if (binfo == null) throw new InvalidOperationException ("OnInsertBreakEvent can't return a null value. If the breakpoint can't be bound or is invalid, a BreakEventInfo with the corresponding status must be returned"); lock (breakpoints) { breakpoints [be] = binfo; } binfo.AttachSession (this, be); } catch (Exception ex) { Breakpoint bp = be as Breakpoint; if (bp != null) OnDebuggerOutput (false, "Could not set breakpoint at location '" + bp.FileName + ":" + bp.Line + " (" + ex.Message + ")\n"); else OnDebuggerOutput (false, "Could not set catchpoint for exception '" + ((Catchpoint)be).ExceptionName + "' (" + ex.Message + ")\n"); HandleException (ex); } }
/// <summary> /// This method can be used by subclasses to set the validity of a breakpoint. /// </summary> protected void SetBreakEventStatus (BreakEvent be, bool isValid, string statusMessge) { lock (breakpoints) { BreakEventInfo bi; if (!breakpoints.TryGetValue (be, out bi)) bi = new BreakEventInfo (null); if (bi.IsValid != isValid || bi.StatusMessage != statusMessge) { bi.IsValid = isValid; bi.StatusMessage = statusMessge; breakpoints [be] = bi; Breakpoints.NotifyStatusChanged (be); } } }
/// <summary> /// Called when information about a breakpoint has changed /// </summary> /// <param name='eventInfo'> /// The break event /// </param> /// <remarks> /// This method is called when some information about the breakpoint changes. /// Notice that the file and line of a breakpoint or the exception name of /// a catchpoint can't be modified. Changes of the Enabled property are /// notified by calling OnEnableBreakEvent. /// </remarks> protected abstract void OnUpdateBreakEvent (BreakEventInfo eventInfo);
void SetBreakEventHandle (BreakEvent be, object handle) { lock (breakpoints) { BreakEventInfo bi; if (!breakpoints.TryGetValue (be, out bi)) bi = new BreakEventInfo (handle); else bi.Handle = handle; breakpoints [be] = bi; } }
protected override void OnEnableBreakEvent(BreakEventInfo binfo, bool enable) { LogWriter(false, "Break enabled " + binfo.ToString()); }
protected override BreakEventInfo OnInsertBreakEvent(BreakEvent be) { LogWriter(false, "Break inserted\n"); Breakpoint bp = be as Breakpoint; if (bp == null) throw new NotSupportedException (); BreakEventInfo bi = new BreakEventInfo (); //lock (debuggerLock) { LogWriter(false, "Location is " + PathHelper.CutOffClassPath(classPathes, bp.FileName) + ":" + bp.Line + '\n'); breaks.Add (new Break (PathHelper.CutOffClassPath (classPathes, bp.FileName), bp.Line)); //} //bi.Handle = TODO: add returned success value (break count etc) bi.SetStatus (BreakEventStatus.Bound, null); return bi; }
protected override void OnRemoveBreakEvent (BreakEventInfo binfo) { if (exited) return; var bi = (BreakInfo) binfo; if (bi.Requests.Count != 0) { foreach (var request in bi.Requests) request.Enabled = false; RemoveQueuedBreakEvents (bi.Requests); } pending_bes.Remove (bi); }
protected override void OnRemoveBreakEvent(BreakEventInfo binfo) { if(LogWriter != null) LogWriter(false, "Break removed " + binfo.ToString()); }
protected override void OnUpdateBreakEvent (BreakEventInfo binfo) { }
protected override void OnUpdateBreakEvent (BreakEventInfo eventInfo) { throw new NotImplementedException (); }