public DbgSymbolGroup(DbgEngDebugger debugger, DEBUG_SCOPE_GROUP scope, DbgStackFrameInfo frame, DbgEngContext context) : base(debugger) { if (null == context) { context = debugger.GetCurrentDbgEngContext(); } if (null == frame) { frame = debugger.GetCurrentScopeFrame(); } Context = context; Frame = frame; using (new DbgEngContextSaver(debugger, context)) { debugger.ExecuteOnDbgEngThread(() => { WDebugSymbols ds5 = (WDebugSymbols)debugger.DebuggerInterface; WDebugSymbolGroup symGroup; CheckHr(ds5.GetScopeSymbolGroup2(scope, null, out symGroup)); m_symGroup = symGroup; Target = debugger.GetCurrentTarget(); }); } } // end constructor
public DbgStackFrameInfo GetTopFrame() { if (null != m_frames) { return(m_frames[0]); } if (null == m_topFrame) { m_topFrame = Debugger.ExecuteOnDbgEngThread(() => { using (new DbgEngContextSaver(Debugger, Context)) { WDebugControl dc = (WDebugControl)Debugger.DebuggerInterface; DEBUG_STACK_FRAME_EX[] frames; int hr = dc.GetStackTraceEx(0, 0, 0, 1, out frames); CheckHr(hr); Util.Assert(1 == frames.Length); return(new DbgStackFrameInfo(Debugger, Thread, frames[0])); } // end using( context saver ) }); } return(m_topFrame); } // end GetTopFrame()
/// <summary> /// Gets the platform-specific RegisterSet object for the specified stack frame, /// using the baseline RegisterSet to compare to when creatin a colorized string. /// </summary> public static DbgRegisterSetBase GetRegisterSet(DbgEngDebugger debugger, DbgStackFrameInfo stackFrame, DbgRegisterSetBase baseline) { if (null == debugger) { throw new ArgumentNullException("debugger"); } var procType = debugger.GetEffectiveProcessorType(); if (debugger.TargetIs32Bit) { if (IMAGE_FILE_MACHINE.THUMB2 == procType) { return(new Arm32RegisterSet(debugger, stackFrame, baseline)); } else if (IMAGE_FILE_MACHINE.I386 == procType) { return(new x86RegisterSet(debugger, stackFrame, baseline)); } else { throw new NotImplementedException(Util.Sprintf("Need to support effective processor type: {0} (32-bit)", procType)); } } else { if (IMAGE_FILE_MACHINE.AMD64 == procType) { return(new x64RegisterSet(debugger, stackFrame, baseline)); } else if (IMAGE_FILE_MACHINE.I386 == procType) { // 64-bit dump of a 32-bit process. return(new x86RegisterSet(debugger, stackFrame, baseline)); } else { throw new NotImplementedException(Util.Sprintf("Need to support effective processor type: {0} (64-bit)", procType)); } } } // end GetRegisterSet()
protected DbgRegisterSetBase(DbgEngDebugger debugger, DbgStackFrameInfo stackFrame, DbgRegisterSetBase baseline) : base(debugger) { if (null == stackFrame) { throw new ArgumentNullException("stackFrame"); } StackFrame = stackFrame; Debugger.ExecuteOnDbgEngThread(() => { m_debugSymbols = (WDebugSymbols)Debugger.DebuggerInterface; m_debugRegisters = (WDebugRegisters)Debugger.DebuggerInterface; m_debugControl = (WDebugControl)Debugger.DebuggerInterface; }); Baseline = baseline; // We used to lazily retrieve values, but that's no good when the context // changes (such as when stepping through code). _GetRegisterInfo(); } // end constructor
} // end property Frames public IEnumerable <DbgStackFrameInfo> EnumerateStackFrames() { if (null != m_frames) { return(m_frames); } m_frames = new List <DbgStackFrameInfo>(); bool noException = false; try { return(Debugger.ExecuteOnDbgEngThread(() => { using (new DbgEngContextSaver(Debugger, Context)) { WDebugControl dc = (WDebugControl)Debugger.DebuggerInterface; /* TODO: I guess frameOffset doesn't do what I think it does... or maybe I need to file a bug. * //int stride = 64; * int stride = 3; * ulong frameOffset = 0; * int hr = 0; * DEBUG_STACK_FRAME_EX[] frames = new DEBUG_STACK_FRAME_EX[ stride ]; * while( true ) * { * uint framesFilled = 0; * hr = dc.GetStackTraceEx( frameOffset, 0, 0, frames, frames.Length, out framesFilled ); * * CheckHr( hr ); * * if( 0 == framesFilled ) * break; * * for( int i = 0; i < framesFilled; i++ ) * { * var newFrame = new StackFrameInfo( Debugger, frames[ i ] ); * m_frames.Add( newFrame ); * //yield return newFrame; hmm, can't mix an iterator with the straight 'return' above * } * * frameOffset += 3; * } // while( keep requesting more frames ) */ DEBUG_STACK_FRAME_EX[] frames; int hr = dc.GetStackTraceEx(0, // frameOffset 0, // stackOffset 0, // instructionOffset MaxFrameCount, out frames); CheckHr(hr); int[] managedFrameIndices; try { managedFrameIndices = new int[Thread.ManagedThreads.Count]; } catch (InvalidOperationException ioe) { // // Likely "Mismatched architecture between this process // and the dac." No managed code information for you, sir. // DbgProvider.RequestExecuteBeforeNextPrompt( Util.Sprintf("Write-Warning 'Could not get managed thread/frame information: {0}'", System.Management.Automation.Language.CodeGeneration.EscapeSingleQuotedStringContent(Util.GetExceptionMessages(ioe)))); managedFrameIndices = new int[0]; // (and remember not to keep trying to get managed info) Debugger.ClrMdDisabled = true; } foreach (var nativeFrame in frames) { ClrStackFrame managedFrame = null; for (int i = 0; i < managedFrameIndices.Length; i++) { var mThread = Thread.ManagedThreads[i]; int mFrameIdx = managedFrameIndices[i]; // It's possible that a thread is marked as a managed // thread, but has no stack frames. (I've seen this, // for instance, at the final breakpoint of a managed // app.) if (0 == mThread.StackTrace.Count) { continue; } if (mFrameIdx >= mThread.StackTrace.Count) { // We've exhausted the managed frames for this // particular managed thread. continue; } var mFrame = mThread.StackTrace[mFrameIdx]; while ((0 == mFrame.InstructionPointer) && (mFrameIdx < (mThread.StackTrace.Count - 1))) // still at least one more frame below? { // It's some sort of "helper" or GC frame or // something, which we need to skip. mFrameIdx++; managedFrameIndices[i] = mFrameIdx; mFrame = mThread.StackTrace[mFrameIdx]; } if (nativeFrame.InstructionOffset == mFrame.InstructionPointer) { managedFrame = mFrame; managedFrameIndices[i] += 1; break; } } var newFrame = new DbgStackFrameInfo(Debugger, m_thread, nativeFrame, managedFrame); m_frames.Add(newFrame); } noException = true; return m_frames; } // end using( context saver ) })); } finally { if (!noException) { m_frames = null; // so we can try again (handy for debugging) } } } // end EnumerateStackFrames()
} // end constructor internal DbgStackInfo(DbgStackFrameInfo contextFrame, int maxFrameCount) : this(contextFrame.Thread) // if ever made public we'd want to validate contextFrame not null { m_contextFrame = contextFrame; MaxFrameCount = maxFrameCount; } // end constructor
internal DbgStackFrameContainer(NsContainer <DbgStackFrameInfo> nsFrame) : base(nsFrame) { Frame = nsFrame.RepresentedObject; } // end constructor
public Arm32RegisterSet(DbgEngDebugger debugger, DbgStackFrameInfo stackFrame, DbgRegisterSetBase baseline) : base(debugger, stackFrame, baseline) { } // end constructor
/// <summary> /// Gets the platform-specific RegisterSet object for the specified stack frame. /// </summary> public static DbgRegisterSetBase GetRegisterSet(DbgEngDebugger debugger, DbgStackFrameInfo stackFrame) { return(GetRegisterSet(debugger, stackFrame, null)); }