int ICorDebugChain.GetStackRange(out ulong pStart, out ulong pEnd) { ulong u; Debug.Assert(m_frames[0].m_depthCLR == (m_frames.Length - 1)); Debug.Assert(m_frames[m_frames.Length - 1].m_depthCLR == 0); CorDebugFrame.GetStackRange(this.Thread, 0, out pStart, out u); CorDebugFrame.GetStackRange(this.Thread, (uint)(m_frames.Length - 1), out u, out pEnd); return(COM_HResults.S_OK); }
public CorDebugFrame GetFrameFromDepthnanoCLR(uint depthnanoCLR) { for (uint iFrame = depthnanoCLR; iFrame < m_frames.Length; iFrame++) { CorDebugFrame frame = m_frames[iFrame]; if (frame.DepthnanoCLR == depthnanoCLR) { return(frame); } } return(null); }
int ICorDebugChain.EnumerateFrames(out ICorDebugFrameEnum ppFrames) { //Reverse the order for the enumerator CorDebugFrame[] frames = new CorDebugFrame[m_frames.Length]; int iFrameSrc = m_frames.Length - 1; for (int iFrameDst = 0; iFrameDst < m_frames.Length; iFrameDst++) { frames[iFrameDst] = m_frames[iFrameSrc]; iFrameSrc--; } ppFrames = new CorDebugEnum(frames, typeof(ICorDebugFrame), typeof(ICorDebugFrameEnum)); return(COM_HResults.S_OK); }
public ManagedCallbackException(CorDebugThread thread, CorDebugFrame frame, uint ip, CorDebugExceptionCallbackType type) : base(thread) { m_type = type; m_frame = frame; m_ip = ip; if (!thread.Engine.Capabilities.ExceptionFilters) { m_fSuspendThreadEvents = (m_type == CorDebugExceptionCallbackType.DEBUG_EXCEPTION_FIRST_CHANCE) || (m_type == CorDebugExceptionCallbackType.DEBUG_EXCEPTION_USER_FIRST_CHANCE); } //Because we are now doing two-pass exception handling, the stack's IP isn't going to be the handler, so //we have to use the IP sent via the breakpointDef and not the stack frame. if (m_frame != null && m_frame.Function != null && m_frame.Function.HasSymbols) { m_ip = m_frame.Function.GetILCLRFromILnanoCLR(m_ip); } }
public ManagedCallbackExceptionUnwind(CorDebugThread thread, CorDebugFrame frame, CorDebugExceptionUnwindCallbackType type) : base(thread) { Debug.Assert(type == CorDebugExceptionUnwindCallbackType.DEBUG_EXCEPTION_INTERCEPTED, "UnwindBegin is not supported"); m_type = type; m_frame = frame; }
private void ExceptionThrown(BreakpointDef breakpointDef) { CorDebugThread thread = this.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 (this.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)); } } }
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 CorDebugStepper(CorDebugFrame frame) : base(frame.AppDomain) { Initialize(frame); }