void HandleBreakEventSet (Event[] es, bool dequeuing) { if (dequeuing && exited) return; OnHandleBreakEventSet (es); bool resume = true; ObjectMirror exception = null; TargetEventType etype = TargetEventType.TargetStopped; BreakEvent breakEvent = null; if (es[0] is ExceptionEvent) { var bad = es.FirstOrDefault (ee => !(ee is ExceptionEvent)); if (bad != null) throw new Exception ("Catchpoint eventset had unexpected event type " + bad.GetType ()); var ev = (ExceptionEvent)es[0]; if (ev.Request == unhandledExceptionRequest) etype = TargetEventType.UnhandledException; else etype = TargetEventType.ExceptionThrown; exception = ev.Exception; if (ev.Request != unhandledExceptionRequest || exception.Type.FullName != "System.Threading.ThreadAbortException") resume = false; } else { //always need to evaluate all breakpoints, some might be tracepoints or conditional bps with counters foreach (Event e in es) { BreakpointEvent be = e as BreakpointEvent; if (be != null) { if (!HandleBreakpoint (e.Thread, be.Request)) { etype = TargetEventType.TargetHitBreakpoint; BreakInfo binfo; if (breakpoints.TryGetValue (be.Request, out binfo)) breakEvent = binfo.BreakEvent; resume = false; } } else if (e is StepEvent) { etype = TargetEventType.TargetStopped; resume = false; } else { throw new Exception ("Break eventset had unexpected event type " + e.GetType ()); } } } if (resume) { //all breakpoints were conditional and evaluated as false vm.Resume (); DequeueEventsForFirstThread (); } else { if (currentStepRequest != null) { currentStepRequest.Enabled = false; currentStepRequest = null; } current_thread = recent_thread = es[0].Thread; TargetEventArgs args = new TargetEventArgs (etype); args.Process = OnGetProcesses () [0]; args.Thread = GetThread (args.Process, current_thread); args.Backtrace = GetThreadBacktrace (current_thread); args.BreakEvent = breakEvent; if (exception != null) activeExceptionsByThread [current_thread.ThreadId] = exception; OnTargetEvent (args); } }
internal void Step(AD7Thread thread, enum_STEPKIND sk, enum_STEPUNIT stepUnit) { if (!isStepping) { if (currentStepRequest == null) currentStepRequest = _vm.CreateStepRequest(thread.ThreadMirror); else { currentStepRequest.Disable(); } isStepping = true; if (stepUnit == enum_STEPUNIT.STEP_LINE || stepUnit == enum_STEPUNIT.STEP_STATEMENT) { switch (sk) { case enum_STEPKIND.STEP_INTO: currentStepRequest.Depth = StepDepth.Into; break; case enum_STEPKIND.STEP_OUT: currentStepRequest.Depth = StepDepth.Out; break; case enum_STEPKIND.STEP_OVER: currentStepRequest.Depth = StepDepth.Over; break; default: return; } } else if (stepUnit == enum_STEPUNIT.STEP_INSTRUCTION) { //TODO: by techcap } else throw new NotImplementedException(); currentStepRequest.Size = StepSize.Line; currentStepRequest.Enable(); } _vm.Resume(); }
void Step (StepDepth depth, StepSize size) { ThreadPool.QueueUserWorkItem (delegate { try { Adaptor.CancelAsyncOperations (); // This call can block, so it has to run in background thread to avoid keeping the main session lock var req = vm.CreateStepRequest (current_thread); req.Depth = depth; req.Size = size; if (assemblyFilters != null && assemblyFilters.Count > 0) req.AssemblyFilter = assemblyFilters; req.Enabled = true; currentStepRequest = req; OnResumed (); vm.Resume (); DequeueEventsForFirstThread (); } catch (Exception ex) { LoggingService.LogError ("Next Line command failed", ex); } }); }
void HandleBreakEventSet (Event[] es, bool dequeuing) { if (dequeuing && exited) return; bool resume = true; bool steppedOut = false; bool steppedInto = false; bool redoCurrentStep = false; ObjectMirror exception = null; TargetEventType etype = TargetEventType.TargetStopped; BreakEvent breakEvent = null; if (es[0] is ExceptionEvent) { var bad = es.FirstOrDefault (ee => ee.EventType != EventType.Exception); if (bad != null) throw new Exception ("Catchpoint eventset had unexpected event type " + bad.GetType ()); var ev = (ExceptionEvent)es[0]; if (ev.Request == unhandledExceptionRequest) etype = TargetEventType.UnhandledException; else etype = TargetEventType.ExceptionThrown; exception = ev.Exception; if (ev.Request != unhandledExceptionRequest || exception.Type.FullName != "System.Threading.ThreadAbortException") resume = false; } else { //always need to evaluate all breakpoints, some might be tracepoints or conditional bps with counters foreach (Event e in es) { if (e.EventType == EventType.Breakpoint) { var be = e as BreakpointEvent; BreakInfo binfo; if (!HandleBreakpoint (e.Thread, be.Request)) { etype = TargetEventType.TargetHitBreakpoint; autoStepInto = false; resume = false; } if (breakpoints.TryGetValue (be.Request, out binfo)) { if (currentStepRequest != null && binfo.Location.ILOffset == currentAddress && e.Thread.Id == currentStepRequest.Thread.Id) redoCurrentStep = true; breakEvent = binfo.BreakEvent; } } else if (e.EventType == EventType.Step) { var stepRequest = e.Request as StepEventRequest; steppedInto = IsStepIntoRequest (stepRequest); steppedOut = IsStepOutRequest (stepRequest); etype = TargetEventType.TargetStopped; resume = false; } else if (e.EventType == EventType.UserBreak) { etype = TargetEventType.TargetStopped; autoStepInto = false; resume = false; } else { throw new Exception ("Break eventset had unexpected event type " + e.GetType ()); } } } if (redoCurrentStep) { StepDepth depth = currentStepRequest.Depth; StepSize size = currentStepRequest.Size; current_thread = recent_thread = es[0].Thread; currentStepRequest.Enabled = false; currentStepRequest = null; Step (depth, size); } else if (resume) { //all breakpoints were conditional and evaluated as false vm.Resume (); DequeueEventsForFirstThread (); } else { if (currentStepRequest != null) { currentStepRequest.Enabled = false; currentStepRequest = null; } current_thread = recent_thread = es[0].Thread; if (exception != null) activeExceptionsByThread [current_thread.ThreadId] = exception; var backtrace = GetThreadBacktrace (current_thread); bool stepOut = false; if (backtrace.FrameCount > 0) { var frame = backtrace.GetFrame (0) as SoftDebuggerStackFrame; currentAddress = frame != null ? frame.Address : -1; if (steppedInto && Options.StepOverPropertiesAndOperators) stepOut = frame != null && IsPropertyOrOperatorMethod (frame.StackFrame.Method); } if (stepOut) { // We will want to call StepInto once StepOut returns... autoStepInto = true; Step (StepDepth.Out, StepSize.Min); } else if (steppedOut && autoStepInto) { autoStepInto = false; Step (StepDepth.Into, StepSize.Min); } else { var args = new TargetEventArgs (etype); args.Process = OnGetProcesses () [0]; args.Thread = GetThread (args.Process, current_thread); args.Backtrace = backtrace; args.BreakEvent = breakEvent; OnTargetEvent (args); } } }
private void HandleStep(StepEvent stepEvent) { if (currentStepRequest != null) { currentStepRequest.Enabled = false; currentStepRequest = null; } _engine.Callback.StepCompleted(_mainThread); logger.Trace("Stepping: {0}:{1}", stepEvent.Method.Name, stepEvent.Location); isStepping = false; }
static bool IsStepIntoRequest (StepEventRequest stepRequest) { return stepRequest.Depth == StepDepth.Into; }
static bool IsStepOutRequest (StepEventRequest stepRequest) { return stepRequest.Depth == StepDepth.Out; }
protected override void OnNextLine () { ThreadPool.QueueUserWorkItem (delegate { Adaptor.CancelAsyncOperations (); // This call can block, so it has to run in background thread to avoid keeping the main session lock var req = vm.CreateStepRequest (current_thread); req.Depth = StepDepth.Over; req.Size = StepSize.Line; if (assemblyFilters != null && assemblyFilters.Count > 0) req.AssemblyFilter = assemblyFilters; req.Enabled = true; currentStepRequest = req; OnResumed (); vm.Resume (); DequeueEventsForFirstThread (); }); }
void HandleEvent (Event e, bool dequeuing) { if (dequeuing && exited) return; bool resume = true; ObjectMirror exception = null; TargetEventType etype = TargetEventType.TargetStopped; #if DEBUG_EVENT_QUEUEING if (!(e is TypeLoadEvent)) Console.WriteLine ("pp event: " + e); #endif OnHandleEvent (e); if (e is AssemblyLoadEvent) { AssemblyLoadEvent ae = (AssemblyLoadEvent)e; bool isExternal = !UpdateAssemblyFilters (ae.Assembly) && userAssemblyNames != null; string flagExt = isExternal? " [External]" : ""; OnDebuggerOutput (false, string.Format ("Loaded assembly: {0}{1}\n", ae.Assembly.Location, flagExt)); } if (e is AssemblyUnloadEvent) { AssemblyUnloadEvent aue = (AssemblyUnloadEvent)e; // Mark affected breakpoints as pending again List<KeyValuePair<EventRequest,BreakInfo>> affectedBreakpoints = new List<KeyValuePair<EventRequest, BreakInfo>> ( breakpoints.Where (x=> (x.Value.Location.Method.DeclaringType.Assembly.Location.Equals (aue.Assembly.Location, StringComparison.OrdinalIgnoreCase))) ); foreach (KeyValuePair<EventRequest,BreakInfo> breakpoint in affectedBreakpoints) { OnDebuggerOutput (false, string.Format ("Re-pending breakpoint at {0}:{1}\n", Path.GetFileName (breakpoint.Value.Location.SourceFile), breakpoint.Value.Location.LineNumber)); breakpoints.Remove (breakpoint.Key); pending_bes.Add (breakpoint.Value.BreakEvent); } // Remove affected types from the loaded types list List<string> affectedTypes = new List<string> ( from pair in types where pair.Value.Assembly.Location.Equals (aue.Assembly.Location, StringComparison.OrdinalIgnoreCase) select pair.Key ); foreach (string typename in affectedTypes) { types.Remove (typename); } foreach (var pair in source_to_type) { pair.Value.RemoveAll (delegate (TypeMirror mirror){ return mirror.Assembly.Location.Equals (aue.Assembly.Location, StringComparison.OrdinalIgnoreCase); }); } OnDebuggerOutput (false, string.Format ("Unloaded assembly: {0}\n", aue.Assembly.Location)); } if (e is VMStartEvent) { //HACK: 2.6.1 VM doesn't emit type load event, so work around it var t = vm.RootDomain.Corlib.GetType ("System.Exception", false, false); if (t != null) ResolveBreakpoints (t); OnVMStartEvent ((VMStartEvent) e); } if (e is TypeLoadEvent) { var t = ((TypeLoadEvent)e).Type; string typeName = t.FullName; if (types.ContainsKey (typeName)) { if (typeName != "System.Exception") LoggingService.LogError ("Type '" + typeName + "' loaded more than once", null); } else { ResolveBreakpoints (t); } } if (e is BreakpointEvent) { BreakpointEvent be = (BreakpointEvent)e; if (!HandleBreakpoint (e.Thread, be.Request)) { etype = TargetEventType.TargetHitBreakpoint; resume = false; } } if (e is ExceptionEvent) { etype = TargetEventType.ExceptionThrown; var ev = (ExceptionEvent)e; exception = ev.Exception; if (ev.Request != unhandledExceptionRequest || exception.Type.FullName != "System.Threading.ThreadAbortException") resume = false; } if (e is StepEvent) { etype = TargetEventType.TargetStopped; resume = false; } if (e is ThreadStartEvent) { ThreadStartEvent ts = (ThreadStartEvent)e; OnDebuggerOutput (false, string.Format ("Thread started: {0}\n", ts.Thread.Name)); } if (resume) vm.Resume (); else { if (currentStepRequest != null) { currentStepRequest.Enabled = false; currentStepRequest = null; } current_thread = recent_thread = e.Thread; TargetEventArgs args = new TargetEventArgs (etype); args.Process = OnGetProcesses () [0]; args.Thread = GetThread (args.Process, current_thread); args.Backtrace = GetThreadBacktrace (current_thread); if (exception != null) activeExceptionsByThread [current_thread.Id] = exception; OnTargetEvent (args); } }
private void DoStep(StepDepth depth) { Contract.Requires(m_stepRequest == null, "m_stepRequest is not null"); Log.WriteLine(TraceLevel.Verbose, "Debugger", "Stepping {0}", depth); m_stepRequest = m_vm.CreateStepRequest(m_currentThread); m_stepRequest.Depth = depth; m_stepRequest.Size = StepBy; m_stepRequest.Enabled = true; m_thread.Resume(); }
internal void OnStep(StepEvent e) { var frame = e.Thread.GetFrames()[0]; // in mono 2.6.7 we could get the location from the event, but that no longer works with mono 2.8 Location location = frame.Location; if (location != null) Log.WriteLine(TraceLevel.Info, "Debugger", "Stepped to {0}:{1:X4} in {2}:{3}", e.Method.FullName, frame.ILOffset, location.SourceFile, location.LineNumber); else Log.WriteLine(TraceLevel.Info, "Debugger", "Stepped to {0}:{1:X4}", e.Method.FullName, frame.ILOffset); m_currentThread = e.Thread; m_stepRequest.Disable(); m_stepRequest = null; var context = new Context(e.Thread, e.Method, frame.ILOffset); Broadcaster.Invoke("debugger processed step event", context); }
internal void OnException(ExceptionEvent e) { var frames = new LiveStack(e.Thread); LiveStackFrame frame = frames[0]; Boss boss = ObjectModel.Create("Application"); var exceptions = boss.Get<IExceptions>(); if (!DoIsIgnoredException(e.Exception.Type, exceptions.Ignored, frame.Method.Name)) { m_currentThread = e.Thread; if (m_stepRequest != null) { m_stepRequest.Disable(); m_stepRequest = null; } if (DebuggerWindows.WriteEvents) m_transcript.WriteLine(Output.Normal, "{0} exception was thrown at {1}:{2:X4}", e.Exception.Type.FullName, frame.Method.FullName, frame.ILOffset); var context = new Context(e.Thread, frame.Method, frame.ILOffset); Broadcaster.Invoke("debugger thrown exception", context); } else { m_transcript.WriteLine(Output.Normal, "Ignoring {0} in {1}:{2}", e.Exception.Type.FullName, frame.Method.DeclaringType.Name, frame.Method.Name); m_thread.Resume(); } }
internal void OnBreakpoint(BreakpointEvent e, ResolvedBreakpoint bp) { m_currentThread = e.Thread; var frames = new LiveStack(m_currentThread); Contract.Assert(BreakpointCondition != null, "BreakpointCondition is null"); DebuggerThread.HandlerAction action = BreakpointCondition(frames[0], bp.BreakPoint); if (action == DebuggerThread.HandlerAction.Suspend) { if (m_stepRequest != null) { m_stepRequest.Disable(); m_stepRequest = null; } Log.WriteLine(TraceLevel.Info, "Debugger", "Hit breakpoint at {0}:{1:X4}", e.Method.FullName, bp.Offset); var context = new Context(e.Thread, e.Method, bp.Offset); Broadcaster.Invoke("debugger processed breakpoint event", context); if (!NSApplication.sharedApplication().isActive()) NSApplication.sharedApplication().activateIgnoringOtherApps(true); } else { Log.WriteLine(TraceLevel.Info, "Debugger", "ignoring breakpoint at {0}:{1:X4} (condition evaluated to false)", e.Method.FullName, bp.Offset); m_thread.Resume(); } }
internal void Step(MonoThread thread, enum_STEPKIND sk) { if (isStepping) return; if (currentStepRequest == null) currentStepRequest = _vm.CreateStepRequest(thread.ThreadMirror); else { currentStepRequest.Disable(); } isStepping = true; switch (sk) { case enum_STEPKIND.STEP_INTO: currentStepRequest.Depth = StepDepth.Into; break; case enum_STEPKIND.STEP_OUT: currentStepRequest.Depth = StepDepth.Out; break; case enum_STEPKIND.STEP_OVER: currentStepRequest.Depth = StepDepth.Over; break; default: return; } currentStepRequest.Size = StepSize.Line; currentStepRequest.Enable(); _vm.Resume(); }