private void Initialize (CorDebugFrame frame) { m_frame = frame; m_thread = frame.Thread; InitializeBreakpointDef (); }
void CheckTimestamp () { if (evalTimestamp != MicroFrameworkDebuggerSession.EvaluationTimestamp) { thread = null; frame = null; corEval = null; } }
public override void CopyFrom (EvaluationContext ctx) { base.CopyFrom (ctx); frame = ((CorEvaluationContext)ctx).frame; frameIndex = ((CorEvaluationContext)ctx).frameIndex; evalTimestamp = ((CorEvaluationContext)ctx).evalTimestamp; Thread = ((CorEvaluationContext)ctx).Thread; Session = ((CorEvaluationContext)ctx).Session; }
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(Utility.COM_HResults.S_OK); }
public CorDebugFrame GetFrameFromDepthTinyCLR(uint depthTinyCLR) { for (uint iFrame = depthTinyCLR; iFrame < m_frames.Length; iFrame++) { CorDebugFrame frame = m_frames[iFrame]; if (frame.DepthTinyCLR == depthTinyCLR) { 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(Utility.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.GetILCLRFromILTinyCLR(m_ip); } }
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 Utility.COM_HResults.S_OK; }
public CorDebugStepper (CorDebugFrame frame) : base (frame.AppDomain) { Initialize (frame); }
internal static StackFrame CreateFrame(MicroFrameworkDebuggerSession session, CorDebugFrame frame) { string file = ""; int line = 0; string method = ""; string lang = ""; if (frame.FrameType == CorFrameType.ILFrame) { if (frame.Function != null) { uint tk = TinyCLR_TypeSystem.SymbollessSupport.TinyCLRTokenFromMethodDefToken(frame.Function.Token); uint md = TinyCLR_TypeSystem.ClassMemberIndexFromTinyCLRToken(tk, frame.Function.Assembly); method = session.Engine.GetMethodName(md, true); var debugData = frame.Function.GetMethodInfo(session)?.DebugInformation; if (debugData != null) { SequencePoint prevSp = null; foreach (var sp in debugData.SequencePoints) { if (sp.Offset > frame.IP) { break; } prevSp = sp; } if (prevSp.Offset != -1) { line = prevSp.StartLine; file = prevSp.Document.Url; } } } lang = "Managed"; } // else if(frame.FrameType == CorFrameType.NativeFrame) // { // frame.GetNativeIP(out address); // method = "<Unknown>"; // lang = "Native"; // } else if (frame.FrameType == CorFrameType.InternalFrame) { switch (((CorDebugInternalFrame)frame).FrameInternalType) { case CorDebugInternalFrameType.STUBFRAME_M2U: method = "[Managed to Native Transition]"; break; case CorDebugInternalFrameType.STUBFRAME_U2M: method = "[Native to Managed Transition]"; break; case CorDebugInternalFrameType.STUBFRAME_LIGHTWEIGHT_FUNCTION: method = "[Lightweight Method Call]"; break; case CorDebugInternalFrameType.STUBFRAME_APPDOMAIN_TRANSITION: method = "[Application Domain Transition]"; break; case CorDebugInternalFrameType.STUBFRAME_FUNC_EVAL: method = "[Function Evaluation]"; break; } } if (method == null) { method = "<Unknown>"; } var loc = new SourceLocation(method, file, line); return(new StackFrame((long)0, loc, lang)); }
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; }
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.GetILCLRFromILTinyCLR (m_ip); } }
int ICorDebugManagedCallback.Exception (CorDebugAppDomain pAppDomain, CorDebugThread pThread, CorDebugFrame pFrame, uint nOffset, CorDebugExceptionCallbackType dwEventType, uint dwFlags) { return 0; }
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.DepthTinyCLR; 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.GetFrameFromDepthTinyCLR(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 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; }
internal static StackFrame CreateFrame(MicroFrameworkDebuggerSession session, CorDebugFrame frame) { string file = ""; int line = 0; string method = ""; string lang = ""; if (frame.FrameType == CorFrameType.ILFrame) { if (frame.Function != null) { uint tk = TinyCLR_TypeSystem.SymbollessSupport.TinyCLRTokenFromMethodDefToken(frame.Function.Token); uint md = TinyCLR_TypeSystem.ClassMemberIndexFromTinyCLRToken(tk, frame.Function.Assembly); method = session.Engine.GetMethodName(md, true); var reader = frame.Function.Assembly.DebugData; if (reader != null) { var sim = new MethodSymbols(new Mono.Cecil.MetadataToken(frame.Function.Token)); //Ugliest hack ever if (reader is Mono.Cecil.Mdb.MdbReader) { for (int i = 0; i < 100; i++) { sim.Variables.Add(new VariableDefinition(null)); } } reader.Read(sim); InstructionSymbol prevSp = new InstructionSymbol(-1, null); foreach (var sp in sim.Instructions) { if (sp.Offset > frame.IP) { break; } prevSp = sp; } if (prevSp.Offset != -1) { line = prevSp.SequencePoint.StartLine; file = prevSp.SequencePoint.Document.Url; } } } lang = "Managed"; } // else if(frame.FrameType == CorFrameType.NativeFrame) // { // frame.GetNativeIP(out address); // method = "<Unknown>"; // lang = "Native"; // } else if (frame.FrameType == CorFrameType.InternalFrame) { switch (((CorDebugInternalFrame)frame).FrameInternalType) { case CorDebugInternalFrameType.STUBFRAME_M2U: method = "[Managed to Native Transition]"; break; case CorDebugInternalFrameType.STUBFRAME_U2M: method = "[Native to Managed Transition]"; break; case CorDebugInternalFrameType.STUBFRAME_LIGHTWEIGHT_FUNCTION: method = "[Lightweight Method Call]"; break; case CorDebugInternalFrameType.STUBFRAME_APPDOMAIN_TRANSITION: method = "[Application Domain Transition]"; break; case CorDebugInternalFrameType.STUBFRAME_FUNC_EVAL: method = "[Function Evaluation]"; break; } } if (method == null) { method = "<Unknown>"; } var loc = new SourceLocation(method, file, line); return(new StackFrame((long)0, loc, lang)); }
private void ExceptionThrown(BreakpointDef breakpointDef) { CorDebugThread thread = this.Process.GetThread(breakpointDef.m_pid); thread.StoppedOnException(); CorDebugFrame frame = thread.Chain.GetFrameFromDepthTinyCLR(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.GetFrameFromDepthTinyCLR(depth); if (frame != null && frame.Function.HasSymbols && frame.Function.PdbxMethod.IsJMC) { Process.EnqueueEvent(new ManagedCallbacks.ManagedCallbackException(thread, frame, frame.IP_TinyCLR, CorDebugExceptionCallbackType.DEBUG_EXCEPTION_USER_FIRST_CHANCE)); break; } if (depth == 0) { break; } } if (!fUnhandled) { frame = thread.Chain.GetFrameFromDepthTinyCLR(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)); } } }
internal static StackFrame CreateFrame (MicroFrameworkDebuggerSession session, CorDebugFrame frame) { string file = ""; int line = 0; string method = ""; string lang = ""; if (frame.FrameType == CorFrameType.ILFrame) { if (frame.Function != null) { uint tk = TinyCLR_TypeSystem.SymbollessSupport.TinyCLRTokenFromMethodDefToken (frame.Function.Token); uint md = TinyCLR_TypeSystem.ClassMemberIndexFromTinyCLRToken (tk, frame.Function.Assembly); method = session.Engine.GetMethodName (md, true); var reader = frame.Function.Assembly.DebugData; if (reader != null) { var sim = new MethodSymbols (new Mono.Cecil.MetadataToken (frame.Function.Token)); //Ugliest hack ever if(reader is Mono.Cecil.Mdb.MdbReader) { for(int i = 0; i < 100; i++) sim.Variables.Add(new VariableDefinition(null)); } reader.Read (sim); InstructionSymbol prevSp = new InstructionSymbol (-1, null); foreach (var sp in sim.Instructions) { if (sp.Offset > frame.IP) break; prevSp = sp; } if (prevSp.Offset != -1) { line = prevSp.SequencePoint.StartLine; file = prevSp.SequencePoint.Document.Url; } } } lang = "Managed"; } // else if(frame.FrameType == CorFrameType.NativeFrame) // { // frame.GetNativeIP(out address); // method = "<Unknown>"; // lang = "Native"; // } else if (frame.FrameType == CorFrameType.InternalFrame) { switch (((CorDebugInternalFrame)frame).FrameInternalType) { case CorDebugInternalFrameType.STUBFRAME_M2U: method = "[Managed to Native Transition]"; break; case CorDebugInternalFrameType.STUBFRAME_U2M: method = "[Native to Managed Transition]"; break; case CorDebugInternalFrameType.STUBFRAME_LIGHTWEIGHT_FUNCTION: method = "[Lightweight Method Call]"; break; case CorDebugInternalFrameType.STUBFRAME_APPDOMAIN_TRANSITION: method = "[Application Domain Transition]"; break; case CorDebugInternalFrameType.STUBFRAME_FUNC_EVAL: method = "[Function Evaluation]"; break; } } if (method == null) method = "<Unknown>"; var loc = new SourceLocation (method, file, line); return new StackFrame ((long)0, loc, lang); }
public CorDebugStepper(CorDebugFrame frame) : base(frame.AppDomain) { Initialize(frame); }