/** * Helper for invoking events. Checks to make sure that handlers * are hooked up to a handler before the handler is invoked. * * We want to allow maximum flexibility by our callers. As such, * we don't require that they call <code>e.Controller.Continue</code>, * nor do we require that this class call it. <b>Someone</b> needs * to call it, however. * * Consequently, if an exception is thrown and the process is stopped, * the process is continued automatically. */ void InternalFireEvent(ManagedCallbackType callbackType,CorEventArgs e) { CorProcess owner; CorController c = e.Controller; Debug.Assert(c!=null); if(c is CorProcess) owner = (CorProcess)c ; else { Debug.Assert(c is CorAppDomain); owner = (c as CorAppDomain).Process; } Debug.Assert(owner!=null); try { owner.DispatchEvent(callbackType,e); } finally { if(e.Continue) { e.Controller.Continue(false); } } }
protected override void HandleEvent(ManagedCallbackType eventId, CorEventArgs args) { m_outer.InternalFireEvent(eventId, args); }
/** * Helper for invoking events. Checks to make sure that handlers * are hooked up to a handler before the handler is invoked. * * We want to allow maximum flexibility by our callers. As such, * we don't require that they call <code>e.Controller.Continue</code>, * nor do we require that this class call it. <b>Someone</b> needs * to call it, however. * * Consequently, if an exception is thrown and the process is stopped, * the process is continued automatically. */ void InternalFireEvent(ManagedCallbackType callbackType, CorEventArgs e) { CorProcess owner = e.Process; Debug.Assert(owner != null); try { owner.DispatchEvent(callbackType, e); } finally { // If the callback marked the event to be continued, then call Continue now. if (e.Continue) { e.Controller.Continue(false); } } }
// Derived class overrides this methdos protected abstract void HandleEvent(ManagedCallbackType eventId, CorEventArgs args);
/// <summary> /// Expose direct dispatch logic so that other event dispatchers can /// use CorProcess's event handlers. /// </summary> /// <param name="callback">callback type to dispatch</param> /// <param name="e">event arguments used to dispatch</param> public void DirectDispatchEvent(ManagedCallbackType callback, CorEventArgs e) { Debug.Assert(callback == e.CallbackType); if (m_callbackAttachedEvent != null) { m_callbackAttachedEvent.Set(); } DispatchEvent(callback, e); }
internal void DispatchEvent(ManagedCallbackType callback, CorEventArgs e) { try { // CorProcess.Continue has an extra abstraction layer. // - The fist call just sets m_callbackAttachedEvent // - future calls go to ICorDebugProcess::Continue. // This ensures that we don't dispatch any callbacks until // after CorProcess.Continue() is called. if (m_callbackAttachedEvent != null) { m_callbackAttachedEvent.WaitOne(); // waits till callbacks are enabled } Debug.Assert((int)callback >= 0 && (int)callback < m_callbacksArray.Length); Delegate d = m_callbacksArray[(int)callback]; if (d != null) { d.DynamicInvoke(new Object[] { this, e }); } } catch (Exception ex) { CorExceptionInCallbackEventArgs e2 = new CorExceptionInCallbackEventArgs(e.Controller, ex); Debug.Assert(false, "Exception in callback: " + ex.ToString()); try { // we need to dispatch the exception in callback error, but we cannot // use DispatchEvent since throwing exception in ExceptionInCallback // would lead to infinite recursion. Debug.Assert(m_callbackAttachedEvent == null); Delegate d = m_callbacksArray[(int)ManagedCallbackType.OnExceptionInCallback]; if (d != null) d.DynamicInvoke(new Object[] { this, e2 }); } catch (Exception ex2) { Debug.Assert(false, "Exception in Exception notification callback: " + ex2.ToString()); // ignore it -- there is nothing we can do. } e.Continue = e2.Continue; } }
internal RawModeStopReason(ManagedCallbackType callbackType, CorEventArgs callbackArgs) { Debug.Assert(callbackArgs != null); m_callbackType = callbackType; m_callbackArgs = callbackArgs; }
internal void DispatchEvent(ManagedCallbackType callback,CorEventArgs e) { try { if( m_callbackAttachedEvent!=null ) m_callbackAttachedEvent.WaitOne(); // waits till callbacks are enabled Debug.Assert((int)callback>=0 && (int)callback<m_callbacksArray.Length); Delegate d = m_callbacksArray[(int)callback]; if( d!=null ) d.DynamicInvoke( new Object[]{this,e}); } catch(Exception ex) { CorExceptionInCallbackEventArgs e2 = new CorExceptionInCallbackEventArgs(e.Controller,ex); Debug.Assert(false,"Exception in callback: "+ex.ToString()); try { // we need to dispatch the exceptin in callback error, but we cannot // use DispatchEvent since throwing exception in ExceptionInCallback // would lead to infinite recursion. Debug.Assert( m_callbackAttachedEvent==null); Delegate d = m_callbacksArray[(int)ManagedCallbackType.OnExceptionInCallback]; if( d!=null ) d.DynamicInvoke( new Object[]{this, e2}); } catch(Exception ex2) { Debug.Assert(false,"Exception in Exception notification callback: "+ex2.ToString()); // ignore it -- there is nothing we can do. } e.Continue = e2.Continue; } }
public MDbgProcessStopController(MDbgProcess process, CorEventArgs eventArgs, bool needAsyncStopCall) { Debug.Assert(process != null); Debug.Assert(eventArgs != null); this.process = process; this.eventArgs = eventArgs; this.needAsyncStopCall = needAsyncStopCall; }
private bool InternalHandleRawMode(ManagedCallbackType callbackType, CorEventArgs callbackArgs) { lock (this) { switch (RawModeType) { case RawMode.None: return false; case RawMode.AlwaysStop: callbackArgs.Continue = false; m_stopReason = new RawModeStopReason(callbackType, callbackArgs); m_stopGo.MarkAsStopped(); m_stopCounter = g_stopCounter++; m_stopEvent.Set(); return true; case RawMode.NeverStop: return true; default: Debug.Assert(false); return false; } } }
// helper for HandleCustomPostCallback() private bool HandleCustomPostCallbackWorker(ManagedCallbackType callbackType, CorEventArgs callbackArgs) { bool stopRequested = false; bool needAsyncStopCall = false; using (MDbgProcessStopController psc = new MDbgProcessStopController(this, callbackArgs, needAsyncStopCall)) { if (PostDebugEvent != null) { PostDebugEvent(this, new CustomPostCallbackEventArgs(psc, callbackType, callbackArgs)); stopRequested = psc.CustomStopRequested; } } // end using return stopRequested; }
// returns true if the CustomPostCallback requested stop. private bool HandleCustomPostCallback(ManagedCallbackType callbackType, CorEventArgs callbackArgs) { CorNativeStopEventArgs nativeStopEventArgs = (callbackArgs as CorNativeStopEventArgs); // If the event is in-band, then we have to lock the MDbgProcess to make sure // the callback is synchronized with other threads. lock (this) { return HandleCustomPostCallbackWorker(callbackType, callbackArgs); } }
/// <summary> /// This must be called at the end of every debug event handler /// </summary> /// <param name="args"></param> private void EndManagedDebugEvent(CorEventArgs args) { // if we are exiting an event with the continue flag set then // the process will be continuing. Otherwise we will trigger this // later in ReallyContinueProcess if (args.Continue) { OnPreContinue(); } }