public ManagedCallbackThread(CorDebugThread thread, EventType eventType) { //breakpoints can happen on virtual threads.. m_thread = thread.GetRealCorDebugThread(); m_eventType = eventType; m_fSuspendThreadEvents = (m_eventType == EventType.CreateThread); }
public static void GetStackRange(CorDebugThread thread, uint depthCLR, out ulong start, out ulong end) { for (CorDebugThread threadT = thread.GetRealCorDebugThread(); threadT != thread; threadT = threadT.NextThread) { Debug.Assert(threadT.IsSuspended); depthCLR += threadT.Chain.NumFrames; } start = depthCLR; end = start; }
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)); } } }
int ICorDebugChain.GetThread(out ICorDebugThread ppThread) { ppThread = m_thread.GetRealCorDebugThread(); return(COM_HResults.S_OK); }