void OnException2(object sender, CorException2EventArgs e) { lock (debugLock) { if (evaluating) { e.Continue = true; return; } } TargetEventArgs args = null; switch (e.EventType) { case CorDebugExceptionCallbackType.DEBUG_EXCEPTION_FIRST_CHANCE: if (!this.Options.ProjectAssembliesOnly && IsCatchpoint(e)) { args = new TargetEventArgs(TargetEventType.ExceptionThrown); } break; case CorDebugExceptionCallbackType.DEBUG_EXCEPTION_USER_FIRST_CHANCE: if (IsCatchpoint(e)) { args = new TargetEventArgs(TargetEventType.ExceptionThrown); } break; case CorDebugExceptionCallbackType.DEBUG_EXCEPTION_CATCH_HANDLER_FOUND: break; case CorDebugExceptionCallbackType.DEBUG_EXCEPTION_UNHANDLED: args = new TargetEventArgs(TargetEventType.UnhandledException); break; } if (args != null) { OnStopped(); e.Continue = false; // If an exception is thrown while stepping, cancel the stepping operation if (stepper != null && stepper.IsActive()) { stepper.Deactivate(); } SetActiveThread(e.Thread); args.Process = GetProcess(process); args.Thread = GetThread(e.Thread); args.Backtrace = new Backtrace(new CorBacktrace(e.Thread, this)); OnTargetEvent(args); } }
private bool IsCatchpoint(CorException2EventArgs e) { // Build up the exception type hierachy CorValue v = e.Thread.CurrentException; List <string> exceptions = new List <string>(); CorType t = v.ExactType; while (t != null) { exceptions.Add(t.GetTypeInfo(this).FullName); t = t.Base; } // See if a catchpoint is set for this exception. foreach (Catchpoint cp in Breakpoints.GetCatchpoints()) { if (cp.Enabled && exceptions.Contains(cp.ExceptionName)) { return(true); } } return(false); }
/// <summary> /// Acts on the debugger callback, based on the stop option policy settings and the /// type of exception thrown. /// </summary> /// <param name="currentProcess">Current MDbgProcess.</param> /// <param name="args">Callback arguments.</param> public override void ActOnCallback(MDbgProcess currentProcess, CustomPostCallbackEventArgs args) { CorException2EventArgs ea = args.CallbackArgs as CorException2EventArgs; CorExceptionUnwind2EventArgs ua = args.CallbackArgs as CorExceptionUnwind2EventArgs; bool bException2 = (ea != null); if (m_exceptionEnhancedOn || (bException2 && (ea.EventType == CorDebugExceptionCallbackType.DEBUG_EXCEPTION_FIRST_CHANCE))) { MDbgThread currentThread = null; currentThread = currentProcess.Threads.GetThreadFromThreadId((args.CallbackArgs as CorThreadEventArgs).Thread.Id); string exceptionType = null; DebuggerBehavior behavior; try { // Getting the current exception may not be implemented. exceptionType = currentThread.CurrentException.TypeName; behavior = DetermineBehavior(exceptionType); } catch (NotImplementedException) { behavior = this.m_default; } switch (behavior) { case DebuggerBehavior.Stop: if (bException2) { args.Controller.Stop(ea.Thread, new ExceptionThrownStopReason(ea.AppDomain, ea.Thread, ea.Frame, ea.Offset, ea.EventType, ea.Flags, m_exceptionEnhancedOn)); } else { args.Controller.Stop(ua.Thread, new ExceptionUnwindStopReason(ua.AppDomain, ua.Thread, ua.EventType, ua.Flags)); } break; case DebuggerBehavior.Log: string output = "Exception thrown: " + currentThread.CurrentException.TypeName + " at function " + currentThread.CurrentFrame.Function.FullName; if (currentThread.CurrentSourcePosition != null) { output += " in source file " + currentThread.CurrentSourcePosition.Path + ":" + currentThread.CurrentSourcePosition.Line; } CommandBase.WriteOutput(output); if (m_exceptionEnhancedOn) { if (bException2) { CommandBase.WriteOutput("Event type: " + ea.EventType); } else { CommandBase.WriteOutput("Event type: " + ua.EventType); } } CommandBase.WriteOutput(""); break; } } }