private void ExceptionCaught(BreakpointDef breakpointDef) { CorDebugThread thread = Process.GetThread(breakpointDef.m_pid); CorDebugFrame frame = thread.Chain.GetFrameFromDepthnanoCLR(breakpointDef.m_depth); Debug.Assert((breakpointDef.m_flags & BreakpointDef.c_EXCEPTION_UNWIND) != 0); Process.EnqueueEvent(new ManagedCallbacks.ManagedCallbackExceptionUnwind(thread, frame, CorDebugExceptionUnwindCallbackType.DEBUG_EXCEPTION_INTERCEPTED)); }
protected CorDebugBreakpointBase(CorDebugProcess process) { m_breakpointDef = new BreakpointDef(); m_breakpointDef.m_id = s_idNext++; m_breakpointDef.m_pid = BreakpointDef.c_PID_ANY; m_appDomain = null; m_process = process; Debug.Assert(s_idNext != s_idNull); }
private void ThreadCreated(BreakpointDef breakpointDef) { CorDebugThread thread = Process.GetThread(breakpointDef.m_pid); Debug.Assert(thread == null || thread.IsVirtualThread); if (thread == null) { thread = new CorDebugThread(Process, breakpointDef.m_pid, null); Process.AddThread(thread); } }
private void EvalComplete(BreakpointDef breakpointDef) { CorDebugThread thread = Process.GetThread(breakpointDef.m_pid); //This currently gets called after BreakpointHit updates the list of threads. //This should nop as long as func-eval happens on separate threads. Debug.Assert(thread == null); Process.RemoveThread(thread); }
private void ThreadTerminated(BreakpointDef breakpointDef) { CorDebugThread thread = Process.GetThread(breakpointDef.m_pid); // Thread could be NULL if this function is called as result of Thread.Abort in // managed application and application does not catch expeption. // ThreadTerminated is called after thread exits in managed application. if (thread != null) { Process.RemoveThread(thread); } }
public override void Hit(BreakpointDef breakpointDef) { #if NO_THREAD_CREATED_EVENTS if ((breakpointDef.m_flags & BreakpointDef.c_EVAL_COMPLETE) != 0) { EvalComplete(breakpointDef); } #else if ((breakpointDef.m_flags & BreakpointDef.c_THREAD_CREATED) != 0) { ThreadCreated(breakpointDef); } else if ((breakpointDef.m_flags & BreakpointDef.c_THREAD_TERMINATED) != 0) { ThreadTerminated(breakpointDef); } #endif else if ((breakpointDef.m_flags & BreakpointDef.c_EXCEPTION_THROWN) != 0) { ExceptionThrown(breakpointDef); } else if ((breakpointDef.m_flags & BreakpointDef.c_EXCEPTION_CAUGHT) != 0) { ExceptionCaught(breakpointDef); } else if ((breakpointDef.m_flags & BreakpointDef.c_ASSEMBLIES_LOADED) != 0) { AssembliesLoaded(breakpointDef); } else if ((breakpointDef.m_flags & BreakpointDef.c_BREAK) != 0) { Break(breakpointDef); } else { Debug.Assert(false, "unknown CLREvent breakpoint"); } }
public override void Hit(BreakpointDef breakpointDef) { CorDebugThread thread = Process.GetThread(breakpointDef.m_pid); Process.EnqueueEvent(new ManagedCallbacks.ManagedCallbackBreakpoint(thread, this, TypeToMarshal)); }
public override bool ShouldBreak(BreakpointDef breakpointDef) { bool fStop = true; CorDebugStepReason reason; //optimize, optimize, optimize No reason to get list of threads, and get thread stack for each step!!! ushort flags = breakpointDef.m_flags; int depthOld = (int)m_frame.DepthnanoCLR; int depthNew = (int)breakpointDef.m_depth; int dDepth = depthNew - depthOld; if ((flags & BreakpointDef.c_STEP) != 0) { if ((flags & BreakpointDef.c_STEP_IN) != 0) { if (this.Process.Engine.Capabilities.ExceptionFilters && breakpointDef.m_depthExceptionHandler == BreakpointDef.c_DEPTH_STEP_INTERCEPT) { reason = CorDebugStepReason.STEP_INTERCEPT; } else { reason = CorDebugStepReason.STEP_CALL; } } else if ((flags & BreakpointDef.c_STEP_OVER) != 0) { reason = CorDebugStepReason.STEP_NORMAL; } else { if (this.Process.Engine.Capabilities.ExceptionFilters & breakpointDef.m_depthExceptionHandler == BreakpointDef.c_DEPTH_STEP_EXCEPTION_HANDLER) { reason = CorDebugStepReason.STEP_EXCEPTION_HANDLER; } else { reason = CorDebugStepReason.STEP_RETURN; } } } else if ((flags & BreakpointDef.c_EXCEPTION_CAUGHT) != 0) { reason = CorDebugStepReason.STEP_EXCEPTION_HANDLER; if (dDepth > 0) { fStop = false; } else if (dDepth == 0) { fStop = (this.Debugging_Execution_BreakpointDef.m_flags & BreakpointDef.c_STEP_OVER) != 0; } else { fStop = true; } } else if ((flags & BreakpointDef.c_THREAD_TERMINATED) != 0) { reason = CorDebugStepReason.STEP_EXIT; this.Active = false; fStop = false; } else { Debug.Assert(false); throw new ApplicationException("Invalid stepper hit received"); } if (m_ranges != null && reason == CorDebugStepReason.STEP_NORMAL && breakpointDef.m_depth == this.Debugging_Execution_BreakpointDef.m_depth) { foreach (COR_DEBUG_STEP_RANGE range in m_ranges) { if (Utility.InRange(breakpointDef.m_IP, range.startOffset, range.endOffset - 1)) { fStop = false; break; } } Debug.Assert(Utility.FImplies(m_ranges != null && m_ranges.Length == 1, fStop)); } if (fStop && reason != CorDebugStepReason.STEP_EXIT) { uint depth = breakpointDef.m_depth; CorDebugFrame frame = this.m_thread.Chain.GetFrameFromDepthnanoCLR(depth); m_ranges = null; Initialize(frame); //Will callback with wrong reason if stepping through internal calls????? //If we don't stop at an internal call, we need to reset/remember the range somehow? //This might be broken if a StepRange is called that causes us to enter an internal function fStop = !m_frame.Function.IsInternal; } m_reasonStopped = reason; return(fStop); }
public override void Hit(BreakpointDef breakpointDef) { this.m_ranges = null; this.Active = false; this.Process.EnqueueEvent(new ManagedCallbacks.ManagedCallbackStepComplete(m_frame.Thread, this, m_reasonStopped)); }
public virtual bool ShouldBreak(BreakpointDef breakpointDef) { return(true); }
public virtual void Hit(BreakpointDef breakpointDef) { }
public virtual bool IsMatch(BreakpointDef breakpointDef) { return(breakpointDef.m_id == m_breakpointDef.m_id); }
private void Break(BreakpointDef breakpointDef) { CorDebugThread thread = Process.GetThread(breakpointDef.m_pid); Process.EnqueueEvent(new ManagedCallbacks.ManagedCallbackBreak(thread)); }
private void AssembliesLoaded(BreakpointDef breakpointDef) { Process.UpdateAssemblies(); }
private void ExceptionThrown(BreakpointDef breakpointDef) { CorDebugThread thread = Process.GetThread(breakpointDef.m_pid); thread.StoppedOnException(); CorDebugFrame frame = thread.Chain.GetFrameFromDepthnanoCLR(breakpointDef.m_depth); bool fIsEval = thread.IsVirtualThread; bool fUnhandled = (breakpointDef.m_depthExceptionHandler == BreakpointDef.c_DEPTH_UNCAUGHT); if (Process.Engine.Capabilities.ExceptionFilters) { switch (breakpointDef.m_depthExceptionHandler) { case BreakpointDef.c_DEPTH_EXCEPTION_FIRST_CHANCE: Process.EnqueueEvent(new ManagedCallbacks.ManagedCallbackException(thread, frame, breakpointDef.m_IP, CorDebugExceptionCallbackType.DEBUG_EXCEPTION_FIRST_CHANCE)); break; case BreakpointDef.c_DEPTH_EXCEPTION_USERS_CHANCE: Process.EnqueueEvent(new ManagedCallbacks.ManagedCallbackException(thread, frame, breakpointDef.m_IP, CorDebugExceptionCallbackType.DEBUG_EXCEPTION_USER_FIRST_CHANCE)); break; case BreakpointDef.c_DEPTH_EXCEPTION_HANDLER_FOUND: Process.EnqueueEvent(new ManagedCallbacks.ManagedCallbackException(thread, frame, breakpointDef.m_IP, CorDebugExceptionCallbackType.DEBUG_EXCEPTION_CATCH_HANDLER_FOUND)); break; } } else { Process.EnqueueEvent(new ManagedCallbacks.ManagedCallbackException(thread, frame, breakpointDef.m_IP, CorDebugExceptionCallbackType.DEBUG_EXCEPTION_FIRST_CHANCE)); uint depthMin = (fUnhandled) ? 0 : breakpointDef.m_depthExceptionHandler; for (uint depth = breakpointDef.m_depth; depth >= depthMin; depth--) { frame = thread.Chain.GetFrameFromDepthnanoCLR(depth); if (frame != null && frame.Function.HasSymbols && frame.Function.PdbxMethod.IsJMC) { Process.EnqueueEvent(new ManagedCallbacks.ManagedCallbackException(thread, frame, frame.IP_nanoCLR, CorDebugExceptionCallbackType.DEBUG_EXCEPTION_USER_FIRST_CHANCE)); break; } if (depth == 0) { break; } } if (!fUnhandled) { frame = thread.Chain.GetFrameFromDepthnanoCLR(breakpointDef.m_depthExceptionHandler); Process.EnqueueEvent(new ManagedCallbacks.ManagedCallbackException(thread, frame, breakpointDef.m_IP, CorDebugExceptionCallbackType.DEBUG_EXCEPTION_CATCH_HANDLER_FOUND)); } } if (fUnhandled) { //eval threads are virtual, and although the physical thread has an unhandled exception, the //virtual thread does not. The eval thread will get killed, but the rest of the thread chain will //survive, no need to confuse cpde by throwing an unhandled exception if (fIsEval) { CorDebugEval eval = thread.CurrentEval; eval.StoppedOnUnhandledException(); Debug.Assert(thread.IsVirtualThread); CorDebugThread threadT = thread.GetRealCorDebugThread(); CorDebugFrame frameT = threadT.Chain.ActiveFrame; //fake event to let debugging of unhandled exception occur. //Frame probably needs to be an InternalStubFrame??? frame = thread.Chain.GetFrameFromDepthCLR(thread.Chain.NumFrames - 1); #if DEBUG CorDebugInternalFrame internalFrame = frame as CorDebugInternalFrame; Debug.Assert(internalFrame != null && internalFrame.FrameType == CorDebugInternalFrameType.STUBFRAME_FUNC_EVAL); #endif Process.EnqueueEvent(new ManagedCallbacks.ManagedCallbackException(thread, frame, 0, CorDebugExceptionCallbackType.DEBUG_EXCEPTION_CATCH_HANDLER_FOUND)); } else { Process.EnqueueEvent(new ManagedCallbacks.ManagedCallbackException(thread, null, uint.MaxValue, CorDebugExceptionCallbackType.DEBUG_EXCEPTION_UNHANDLED)); } } }