From 263281a2f0f6eeea80849a9616bb94e31ffd7ea5 Mon Sep 17 00:00:00 2001 From: kudzu_cp <6d05c8c8ef5431987001abfdb2eadc9593ac9498> Date: Sun, 12 Aug 2012 15:29:07 +0000 Subject: [PATCH] Faster stepping. --- .../AD7.Impl/AD7Process.cs | 5 +- .../AD7.Impl/AD7Thread.cs | 64 +++++++++++-------- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/source2/Debug/Cosmos.Debug.VSDebugEngine/AD7.Impl/AD7Process.cs b/source2/Debug/Cosmos.Debug.VSDebugEngine/AD7.Impl/AD7Process.cs index e0d242aee..f0fe9467b 100644 --- a/source2/Debug/Cosmos.Debug.VSDebugEngine/AD7.Impl/AD7Process.cs +++ b/source2/Debug/Cosmos.Debug.VSDebugEngine/AD7.Impl/AD7Process.cs @@ -25,7 +25,9 @@ namespace Cosmos.Debug.VSDebugEngine { protected readonly NameValueCollection mDebugInfo; protected LaunchType mLaunch; internal DebugInfo mDebugInfoDb; - private int mProcessExitEventSent = 0; + protected int mProcessExitEventSent = 0; + // Cached stack frame. See comments in AD7Thread regading this. + public IEnumDebugFrameInfo2 mStackFrame; // Connection to target environment. Usually serial but is // abstracted to allow other transports (ethernet, etc) @@ -261,6 +263,7 @@ namespace Cosmos.Debug.VSDebugEngine { } } + mStackFrame = null; mCurrentAddress = aAddress; if (xBoundBreakpoints.Count == 0) { // if no matching breakpoints are found then its one of the following: diff --git a/source2/Debug/Cosmos.Debug.VSDebugEngine/AD7.Impl/AD7Thread.cs b/source2/Debug/Cosmos.Debug.VSDebugEngine/AD7.Impl/AD7Thread.cs index f4b40f462..9ec413892 100644 --- a/source2/Debug/Cosmos.Debug.VSDebugEngine/AD7.Impl/AD7Thread.cs +++ b/source2/Debug/Cosmos.Debug.VSDebugEngine/AD7.Impl/AD7Thread.cs @@ -9,10 +9,10 @@ using Cosmos.Debug.Common; namespace Cosmos.Debug.VSDebugEngine { // This class implements IDebugThread2 which represents a thread running in a program. public class AD7Thread : IDebugThread2 { - readonly AD7Engine mEngine; + protected readonly AD7Engine mEngine; + protected readonly AD7Process mProcess; //readonly DebuggedThread m_debuggedThread; const string ThreadNameString = "Cosmos Kernel Main Thread"; - protected AD7Process mProcess; public AD7Thread(AD7Engine aEngine, AD7Process aProcess) { //, DebuggedThread debuggedThread) mEngine = aEngine; @@ -38,35 +38,45 @@ namespace Cosmos.Debug.VSDebugEngine { // Real engines will most likely want to cache this information to avoid recomputing it each time it is asked for, // and or construct it on demand instead of walking the entire stack. int IDebugThread2.EnumFrameInfo(enum_FRAMEINFO_FLAGS aFieldSpec, uint aRadix, out IEnumDebugFrameInfo2 oEnumObject) { - // Ask the lower-level to perform a stack walk on this thread - //m_engine.DebuggedProcess.DoStackWalk(this.m_debuggedThread); - oEnumObject = null; - try { - //System.Collections.Generic.List stackFrames = this.m_debuggedThread.StackFrames; - //int numStackFrames = stackFrames.Count; - FRAMEINFO[] xFrameInfoArray; + // Check mStackFrame, not address because it is possible for 2 sequential breaks to be on the same address + // but in that case we would need a new stack frame. + // + // EnumFrameInfo is called several times on each break becuase "different callers can call with different flags". + // We ignore flags through and always return full, but EnumFrameInfo gets called half a dozen times which is slow + // if we refresh each and every time. So we cache our info. + if (mProcess.mStackFrame == null) { + // Ask the lower-level to perform a stack walk on this thread + //m_engine.DebuggedProcess.DoStackWalk(this.m_debuggedThread); + oEnumObject = null; + try { + //System.Collections.Generic.List stackFrames = this.m_debuggedThread.StackFrames; + //int numStackFrames = stackFrames.Count; + FRAMEINFO[] xFrameInfoArray; - //if (numStackFrames == 0) { - // failed to walk any frames. Only return the top frame. - xFrameInfoArray = new FRAMEINFO[1]; - AD7StackFrame xFrame = new AD7StackFrame(mEngine, this, mProcess); - xFrame.SetFrameInfo((enum_FRAMEINFO_FLAGS)aFieldSpec, out xFrameInfoArray[0]); - //} else { - //frameInfoArray = new FRAMEINFO[numStackFrames]; + //if (numStackFrames == 0) { + // failed to walk any frames. Only return the top frame. - //for (int i = 0; i < numStackFrames; i++) { - //AD7StackFrame frame = new AD7StackFrame(m_engine, this, stackFrames[i]); - //frame.SetFrameInfo(dwFieldSpec, out frameInfoArray[i]); - //} - //} + xFrameInfoArray = new FRAMEINFO[1]; + var xFrame = new AD7StackFrame(mEngine, this, mProcess); + xFrame.SetFrameInfo((enum_FRAMEINFO_FLAGS)aFieldSpec, out xFrameInfoArray[0]); - oEnumObject = new AD7FrameInfoEnum(xFrameInfoArray); - } catch (Exception e) { - //catch (ComponentException e) { - // return e.HResult; - //} - return EngineUtils.UnexpectedException(e); + //} else { + //frameInfoArray = new FRAMEINFO[numStackFrames]; + //for (int i = 0; i < numStackFrames; i++) { + //AD7StackFrame frame = new AD7StackFrame(m_engine, this, stackFrames[i]); + //frame.SetFrameInfo(dwFieldSpec, out frameInfoArray[i]); + //} + //} + + mProcess.mStackFrame = new AD7FrameInfoEnum(xFrameInfoArray); + } catch (Exception e) { + //catch (ComponentException e) { + // return e.HResult; + //} + return EngineUtils.UnexpectedException(e); + } } + oEnumObject = mProcess.mStackFrame; return VSConstants.S_OK; }