summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve MacLean <Steve.MacLean@microsoft.com>2019-10-22 16:58:15 -0400
committerHyungju Lee <leee.lee@samsung.com>2020-10-30 18:27:38 +0900
commitbe1aa1bf368dd47765d429ee0e557d8cb26f9bfd (patch)
tree6121d87a7d7a547b18e4bb1f8f2021af23d223aa
parent4c3b471c380dcc01579c18ae5756480d27cd1ea1 (diff)
downloadcoreclr-be1aa1bf368dd47765d429ee0e557d8cb26f9bfd.tar.gz
coreclr-be1aa1bf368dd47765d429ee0e557d8cb26f9bfd.tar.bz2
coreclr-be1aa1bf368dd47765d429ee0e557d8cb26f9bfd.zip
* Make ControllerStackInfo::m_returnFrame private * Make ControllerStackInfo always capture a return frame In case the active frame has no managed caller, capture the unmanaged frame * Fix step over stackalloc Generalize handling of stack allocations and stepping * Fix GetFunctionFromToken() argument checking Check token type is a method before creating a CordbFunction. Add extra assert to check for invalid tokens
-rw-r--r--src/debug/di/module.cpp3
-rw-r--r--src/debug/di/rsfunction.cpp1
-rw-r--r--src/debug/di/rspriv.h2
-rw-r--r--src/debug/ee/controller.cpp143
-rw-r--r--src/debug/ee/controller.h13
-rw-r--r--src/debug/ee/frameinfo.cpp2
-rw-r--r--src/debug/ee/frameinfo.h8
-rw-r--r--src/inc/regdisp.h2
8 files changed, 77 insertions, 97 deletions
diff --git a/src/debug/di/module.cpp b/src/debug/di/module.cpp
index 5fb335e6d5..809d005df3 100644
--- a/src/debug/di/module.cpp
+++ b/src/debug/di/module.cpp
@@ -1550,7 +1550,8 @@ HRESULT CordbModule::GetFunctionFromToken(mdMethodDef token,
RSLockHolder lockHolder(GetProcess()->GetProcessLock());
// Check token is valid.
- if ((token == mdMethodDefNil) ||
+ if ((token == mdMethodDefNil) ||
+ (TypeFromToken(token) != mdtMethodDef) ||
(!GetMetaDataImporter()->IsValidToken(token)))
{
ThrowHR(E_INVALIDARG);
diff --git a/src/debug/di/rsfunction.cpp b/src/debug/di/rsfunction.cpp
index 82ac87530d..7dca9826f7 100644
--- a/src/debug/di/rsfunction.cpp
+++ b/src/debug/di/rsfunction.cpp
@@ -49,6 +49,7 @@ CordbFunction::CordbFunction(CordbModule * m,
m_methodSigParserCached = SigParser(NULL, 0);
_ASSERTE(enCVersion >= CorDB_DEFAULT_ENC_FUNCTION_VERSION);
+ _ASSERTE(TypeFromToken(m_MDToken) == mdtMethodDef);
}
diff --git a/src/debug/di/rspriv.h b/src/debug/di/rspriv.h
index 6e4a93fb90..237af6b88a 100644
--- a/src/debug/di/rspriv.h
+++ b/src/debug/di/rspriv.h
@@ -5537,7 +5537,7 @@ private:
RSSmartPtr<CordbNativeCode> m_nativeCode;
// Metadata Token for the IL function. Scoped to m_module.
- mdMethodDef m_MDToken;
+ const mdMethodDef m_MDToken;
// EnC version number of this instance
SIZE_T m_dwEnCVersionNumber;
diff --git a/src/debug/ee/controller.cpp b/src/debug/ee/controller.cpp
index a82666d5cf..183bf3a756 100644
--- a/src/debug/ee/controller.cpp
+++ b/src/debug/ee/controller.cpp
@@ -336,8 +336,8 @@ void ControllerStackInfo::GetStackInfo(
if (result == SWA_DONE)
{
- _ASSERTE(!m_returnFound);
- m_returnFrame = m_activeFrame;
+ _ASSERTE(!HasReturnFrame()); // We didn't find a managed return frame
+ _ASSERTE(HasReturnFrame(true)); // All threads have at least one unmanaged frame
}
}
@@ -418,14 +418,6 @@ StackWalkAction ControllerStackInfo::WalkStack(FrameInfo *pInfo, void *data)
if (i->m_activeFound )
{
- // We care if the current frame is unmanaged (in case a managed stepper is initiated
- // on a thread currently in unmanaged code). But since we can't step-out to UM frames,
- // we can just skip them in the stack walk.
- if (!pInfo->managed)
- {
- return SWA_CONTINUE;
- }
-
if (pInfo->chainReason == CHAIN_CLASS_INIT)
i->m_specialChainReason = pInfo->chainReason;
@@ -439,7 +431,9 @@ StackWalkAction ControllerStackInfo::WalkStack(FrameInfo *pInfo, void *data)
i->m_returnFound = true;
- return SWA_ABORT;
+ // We care if the current frame is unmanaged
+ // Continue unless we found a managed return frame.
+ return pInfo->managed ? SWA_ABORT : SWA_CONTINUE;
}
}
else
@@ -2483,10 +2477,10 @@ bool DebuggerController::MatchPatch(Thread *thread,
// !!! This check should really be != , but there is some ambiguity about which frame is the parent frame
// in the destination returned from Frame::TraceFrame, so this allows some slop there.
- if (info.HasReturnFrame() && IsCloserToLeaf(info.m_returnFrame.fp, patch->fp))
+ if (info.HasReturnFrame() && IsCloserToLeaf(info.GetReturnFrame().fp, patch->fp))
{
LOG((LF_CORDB, LL_INFO10000, "Patch hit but frame not matched at %p (current=%p, patch=%p)\n",
- patch->address, info.m_returnFrame.fp.GetSPValue(), patch->fp.GetSPValue()));
+ patch->address, info.GetReturnFrame().fp.GetSPValue(), patch->fp.GetSPValue()));
return false;
}
@@ -3761,14 +3755,14 @@ bool DebuggerController::DispatchTraceCall(Thread *thread,
_ASSERTE(info.HasReturnFrame());
// This check makes sure that we don't do this logic for inlined frames.
- if (info.m_returnFrame.md->IsILStub())
+ if (info.GetReturnFrame().md->IsILStub())
{
// Make sure that the frame pointer of the active frame is actually
// the address of an exit frame.
_ASSERTE( (static_cast<Frame*>(info.m_activeFrame.fp.GetSPValue()))->GetFrameType()
== Frame::TYPE_EXIT );
- _ASSERTE(!info.m_returnFrame.HasChainMarker());
- fpToCheck = info.m_returnFrame.fp;
+ _ASSERTE(!info.GetReturnFrame().HasChainMarker());
+ fpToCheck = info.GetReturnFrame().fp;
}
}
@@ -5094,14 +5088,14 @@ bool DebuggerStepper::IsRangeAppropriate(ControllerStackInfo *info)
return false;
}
- FrameInfo *realFrame;
+ const FrameInfo *realFrame;
#if defined(WIN64EXCEPTIONS)
bool fActiveFrameIsFunclet = info->m_activeFrame.IsNonFilterFuncletFrame();
if (fActiveFrameIsFunclet)
{
- realFrame = &(info->m_returnFrame);
+ realFrame = &(info->GetReturnFrame());
}
else
#endif // WIN64EXCEPTIONS
@@ -5121,40 +5115,23 @@ bool DebuggerStepper::IsRangeAppropriate(ControllerStackInfo *info)
}
#if defined(WIN64EXCEPTIONS)
- // There are two scenarios which make this function more complicated on WIN64.
+ // There are three scenarios which make this function more complicated on WIN64.
// 1) We initiate a step in the parent method or a funclet but end up stepping into another funclet closer to the leaf.
// a) start in the parent method
// b) start in a funclet
// 2) We initiate a step in a funclet but end up stepping out to the parent method or a funclet closer to the root.
// a) end up in the parent method
// b) end up in a funclet
+ // 3) We initiate a step and then change stack allocation within the method or funclet
// In both cases the range of the stepper should still be appropriate.
bool fValidParentMethodFP = (m_fpParentMethod != LEAF_MOST_FRAME);
- if (fActiveFrameIsFunclet)
- {
- // Scenario 1a
- if (m_fp == info->m_returnFrame.fp)
- {
- LOG((LF_CORDB,LL_INFO10000, "DS::IRA: returning TRUE\n"));
- return true;
- }
- // Scenario 1b & 2b have the same condition
- else if (fValidParentMethodFP && (m_fpParentMethod == info->m_returnFrame.fp))
- {
- LOG((LF_CORDB,LL_INFO10000, "DS::IRA: returning TRUE\n"));
- return true;
- }
- }
- else
+ // All scenarios have the same condition
+ if (fValidParentMethodFP && (m_fpParentMethod == info->GetReturnFrame(true).fp))
{
- // Scenario 2a
- if (fValidParentMethodFP && (m_fpParentMethod == info->m_activeFrame.fp))
- {
- LOG((LF_CORDB,LL_INFO10000, "DS::IRA: returning TRUE\n"));
- return true;
- }
+ LOG((LF_CORDB,LL_INFO10000, "DS::IRA: (parent SP) returning TRUE\n"));
+ return true;
}
#endif // WIN64EXCEPTIONS
@@ -5225,7 +5202,7 @@ bool DebuggerStepper::DetectHandleInterceptors(ControllerStackInfo *info)
{
LOG((LF_CORDB,LL_INFO10000,"DS::DHI: Start DetectHandleInterceptors\n"));
LOG((LF_CORDB,LL_INFO10000,"DS::DHI: active frame=0x%08x, has return frame=%d, return frame=0x%08x m_reason:%d\n",
- info->m_activeFrame.frame, info->HasReturnFrame(), info->m_returnFrame.frame, m_reason));
+ info->m_activeFrame.frame, info->HasReturnFrame(), info->GetReturnFrame().frame, m_reason));
// If this is a normal step, then we want to continue stepping, even if we
// are in an interceptor.
@@ -5246,7 +5223,7 @@ bool DebuggerStepper::DetectHandleInterceptors(ControllerStackInfo *info)
if (!((CorDebugIntercept)info->m_activeFrame.frame->GetInterception() & Frame::Interception(m_rgfInterceptStop)))
{
LOG((LF_CORDB,LL_INFO10000,"DS::DHI: Stepping out b/c of excluded frame type:0x%x\n",
- info->m_returnFrame. frame->GetInterception()));
+ info->m_activeFrame.frame->GetInterception()));
fAttemptStepOut = true;
}
@@ -5260,14 +5237,14 @@ bool DebuggerStepper::DetectHandleInterceptors(ControllerStackInfo *info)
if ((m_reason == STEP_EXCEPTION_FILTER) ||
(info->HasReturnFrame() &&
- info->m_returnFrame.frame != NULL &&
- info->m_returnFrame.frame != FRAME_TOP &&
- info->m_returnFrame.frame->GetInterception() != Frame::INTERCEPTION_NONE))
+ info->GetReturnFrame().frame != NULL &&
+ info->GetReturnFrame().frame != FRAME_TOP &&
+ info->GetReturnFrame().frame->GetInterception() != Frame::INTERCEPTION_NONE))
{
if (m_reason == STEP_EXCEPTION_FILTER)
{
// Exceptions raised inside of the EE by COMPlusThrow, FCThrow, etc will not
- // insert an ExceptionFrame, and hence info->m_returnFrame.frame->GetInterception()
+ // insert an ExceptionFrame, and hence info->GetReturnFrame().frame->GetInterception()
// will not be accurate. Hence we use m_reason instead
if (!(Frame::INTERCEPTION_EXCEPTION & Frame::Interception(m_rgfInterceptStop)))
@@ -5276,10 +5253,10 @@ bool DebuggerStepper::DetectHandleInterceptors(ControllerStackInfo *info)
fAttemptStepOut = true;
}
}
- else if (!(info->m_returnFrame.frame->GetInterception() & Frame::Interception(m_rgfInterceptStop)))
+ else if (!(info->GetReturnFrame().frame->GetInterception() & Frame::Interception(m_rgfInterceptStop)))
{
LOG((LF_CORDB,LL_INFO10000,"DS::DHI: Stepping out b/c of excluded return frame type:0x%x\n",
- info->m_returnFrame.frame->GetInterception()));
+ info->GetReturnFrame().frame->GetInterception()));
fAttemptStepOut = true;
}
@@ -5994,7 +5971,7 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
AddBindAndActivateNativeManagedPatch(info->m_activeFrame.md,
ji,
offset,
- info->m_returnFrame.fp,
+ info->GetReturnFrame().fp,
NULL);
return true;
}
@@ -6013,7 +5990,7 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
AddBindAndActivateNativeManagedPatch(info->m_activeFrame.md,
ji,
offset,
- info->m_returnFrame.fp,
+ info->GetReturnFrame().fp,
NULL);
return true;
@@ -6031,7 +6008,7 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
AddBindAndActivateNativeManagedPatch(info->m_activeFrame.md,
ji,
CodeRegionInfo::GetCodeRegionInfo(ji, info->m_activeFrame.md).AddressToOffset(walker.GetNextIP()),
- info->m_returnFrame.fp,
+ info->GetReturnFrame().fp,
NULL);
return true;
}
@@ -6043,7 +6020,7 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
AddBindAndActivateNativeManagedPatch(info->m_activeFrame.md,
ji,
offset,
- info->m_returnFrame.fp,
+ info->GetReturnFrame().fp,
NULL);
return true;
}
@@ -6061,7 +6038,7 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
AddBindAndActivateNativeManagedPatch(info->m_activeFrame.md,
ji,
offset,
- info->m_returnFrame.fp,
+ info->GetReturnFrame().fp,
NULL);
LOG((LF_CORDB,LL_INFO10000,"DS0x%x m_reason=STEP_CALL 2\n",
@@ -6084,7 +6061,7 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
AddBindAndActivateNativeManagedPatch(info->m_activeFrame.md,
ji,
offset,
- info->m_returnFrame.fp,
+ info->GetReturnFrame().fp,
NULL);
LOG((LF_CORDB,LL_INFO10000,"DS 0x%x m_reason=STEP_CALL4\n",this));
@@ -6103,7 +6080,7 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
AddBindAndActivateNativeManagedPatch(info->m_activeFrame.md,
ji,
offset,
- info->m_returnFrame.fp,
+ info->GetReturnFrame().fp,
NULL);
return true;
}
@@ -6197,31 +6174,31 @@ void DebuggerStepper::TrapStepOut(ControllerStackInfo *info, bool fForceTraditio
_ASSERTE(info->HasReturnFrame());
#ifdef _TARGET_ARM_
- while (info->HasReturnFrame() && info->m_activeFrame.md != info->m_returnFrame.md)
+ while (info->HasReturnFrame() && info->m_activeFrame.md != info->GetReturnFrame().md)
{
StackTraceTicket ticket(info);
- returnInfo.GetStackInfo(ticket, GetThread(), info->m_returnFrame.fp, NULL);
+ returnInfo.GetStackInfo(ticket, GetThread(), info->GetReturnFrame().fp, NULL);
info = &returnInfo;
}
_ASSERTE(info->HasReturnFrame());
#endif
- _ASSERTE(info->m_activeFrame.md == info->m_returnFrame.md);
+ _ASSERTE(info->m_activeFrame.md == info->GetReturnFrame().md);
if (m_eMode == cStepOut)
{
StackTraceTicket ticket(info);
- returnInfo.GetStackInfo(ticket, GetThread(), info->m_returnFrame.fp, NULL);
+ returnInfo.GetStackInfo(ticket, GetThread(), info->GetReturnFrame().fp, NULL);
info = &returnInfo;
}
else
{
- _ASSERTE(info->m_returnFrame.managed);
- _ASSERTE(info->m_returnFrame.frame == NULL);
+ _ASSERTE(info->GetReturnFrame().managed);
+ _ASSERTE(info->GetReturnFrame().frame == NULL);
- MethodDesc *md = info->m_returnFrame.md;
- dji = info->m_returnFrame.GetJitInfoFromFrame();
+ MethodDesc *md = info->GetReturnFrame().md;
+ dji = info->GetReturnFrame().GetJitInfoFromFrame();
// The return value of a catch funclet is the control PC to resume to.
// The return value of a finally funclet has no meaning, so we need to check
@@ -6236,17 +6213,17 @@ void DebuggerStepper::TrapStepOut(ControllerStackInfo *info, bool fForceTraditio
{
SIZE_T reloffset = dji->m_codeRegionInfo.AddressToOffset((BYTE*)resumePC);
- AddBindAndActivateNativeManagedPatch(info->m_returnFrame.md,
+ AddBindAndActivateNativeManagedPatch(info->GetReturnFrame().md,
dji,
reloffset,
- info->m_returnFrame.fp,
+ info->GetReturnFrame().fp,
NULL);
LOG((LF_CORDB, LL_INFO10000,
"DS::TSO:normally managed code AddPatch"
" in %s::%s, offset 0x%x, m_reason=%d\n",
- info->m_returnFrame.md->m_pszDebugClassName,
- info->m_returnFrame.md->m_pszDebugMethodName,
+ info->GetReturnFrame().md->m_pszDebugClassName,
+ info->GetReturnFrame().md->m_pszDebugMethodName,
reloffset, m_reason));
// Do not set m_reason to STEP_RETURN here. Logically, the funclet and the parent method are the
@@ -6289,7 +6266,7 @@ void DebuggerStepper::TrapStepOut(ControllerStackInfo *info, bool fForceTraditio
// not to report the managed frame that was at the same SP. However the unmanaged
// frame might be used in the mixed-mode step out case so I don't suppress it
// there.
- returnInfo.GetStackInfo(ticket, GetThread(), info->m_returnFrame.fp, NULL, !(m_rgfMappingStop & STOP_UNMANAGED));
+ returnInfo.GetStackInfo(ticket, GetThread(), info->GetReturnFrame().fp, NULL, !(m_rgfMappingStop & STOP_UNMANAGED));
info = &returnInfo;
#ifdef _DEBUG
@@ -6353,7 +6330,7 @@ void DebuggerStepper::TrapStepOut(ControllerStackInfo *info, bool fForceTraditio
AddBindAndActivateNativeManagedPatch(info->m_activeFrame.md,
dji,
reloffset,
- info->m_returnFrame.fp,
+ info->GetReturnFrame().fp,
NULL);
LOG((LF_CORDB, LL_INFO10000,
@@ -6508,11 +6485,11 @@ void DebuggerStepper::TrapStepOut(ControllerStackInfo *info, bool fForceTraditio
LOG((LF_CORDB, LL_INFO10000,
"DS::TSO: Setting unmanaged trace patch at 0x%x(%x)\n",
GetControlPC(&(info->m_activeFrame.registers)),
- info->m_returnFrame.fp.GetSPValue()));
+ info->GetReturnFrame().fp.GetSPValue()));
AddAndActivateNativePatchForAddress((CORDB_ADDRESS_TYPE *)GetControlPC(&(info->m_activeFrame.registers)),
- info->m_returnFrame.fp,
+ info->GetReturnFrame().fp,
FALSE,
TRACE_UNMANAGED);
@@ -6566,16 +6543,16 @@ void DebuggerStepper::StepOut(FramePointer fp, StackTraceTicket ticket)
m_fp = info.m_activeFrame.fp;
#if defined(WIN64EXCEPTIONS)
// We need to remember the parent method frame pointer here so that we will recognize
- // the range of the stepper as being valid when we return to the parent method.
- if (info.m_activeFrame.IsNonFilterFuncletFrame())
+ // the range of the stepper as being valid when we return to the parent method or stackalloc.
+ if (info.HasReturnFrame(true))
{
- m_fpParentMethod = info.m_returnFrame.fp;
+ m_fpParentMethod = info.GetReturnFrame(true).fp;
}
#endif // WIN64EXCEPTIONS
m_eMode = cStepOut;
- _ASSERTE((fp == LEAF_MOST_FRAME) || (info.m_activeFrame.md != NULL) || (info.m_returnFrame.md != NULL));
+ _ASSERTE((fp == LEAF_MOST_FRAME) || (info.m_activeFrame.md != NULL) || (info.GetReturnFrame().md != NULL));
TrapStepOut(&info);
EnableUnwind(m_fp);
@@ -6837,7 +6814,7 @@ bool DebuggerStepper::Step(FramePointer fp, bool in,
info.GetStackInfo(ticket, thread, fp, context);
_ASSERTE((fp == LEAF_MOST_FRAME) || (info.m_activeFrame.md != NULL) ||
- (info.m_returnFrame.md != NULL));
+ (info.GetReturnFrame().md != NULL));
m_stepIn = in;
@@ -6905,10 +6882,10 @@ bool DebuggerStepper::Step(FramePointer fp, bool in,
m_fp = info.m_activeFrame.fp;
#if defined(WIN64EXCEPTIONS)
// We need to remember the parent method frame pointer here so that we will recognize
- // the range of the stepper as being valid when we return to the parent method.
- if (info.m_activeFrame.IsNonFilterFuncletFrame())
+ // the range of the stepper as being valid when we return to the parent method or stackalloc.
+ if (info.HasReturnFrame(true))
{
- m_fpParentMethod = info.m_returnFrame.fp;
+ m_fpParentMethod = info.GetReturnFrame(true).fp;
}
#endif // WIN64EXCEPTIONS
}
@@ -7600,8 +7577,8 @@ void DebuggerStepper::PrepareForSendEvent(StackTraceTicket ticket)
#if !defined(WIN64EXCEPTIONS)
IsCloserToRoot(m_fpStepInto, csi.m_activeFrame.fp)
#else
- IsCloserToRoot(m_fpStepInto, (csi.m_activeFrame.IsNonFilterFuncletFrame() ? csi.m_returnFrame.fp : csi.m_activeFrame.fp))
-#endif // WIN64EXCEPTIONS
+ IsCloserToRoot(m_fpStepInto, (csi.m_activeFrame.IsNonFilterFuncletFrame() ? csi.GetReturnFrame().fp : csi.m_activeFrame.fp))
+#endif // FEATURE_EH_FUNCLETS
)
{
@@ -7815,7 +7792,7 @@ bool DebuggerJMCStepper::TrapStepInHelper(
AddBindAndActivateNativeManagedPatch(pInfo->m_activeFrame.md,
dji,
offset,
- pInfo->m_returnFrame.fp,
+ pInfo->GetReturnFrame().fp,
NULL);
EnableMethodEnter();
diff --git a/src/debug/ee/controller.h b/src/debug/ee/controller.h
index 7172662f48..0d4776dd45 100644
--- a/src/debug/ee/controller.h
+++ b/src/debug/ee/controller.h
@@ -140,15 +140,15 @@ private:
* FrameInfo m_activeFrame: A FrameInfo
* describing the target frame. This should always be valid after a
* call to GetStackInfo.
+ *
+ * private:
+ * bool m_activeFound: Set to true if we found the target frame.
+ * bool m_returnFound: Set to true if we found the target's return frame.
*
* FrameInfo m_returnFrame: A FrameInfo
* describing the frame above the target frame, if target's
* return frame were found (call HasReturnFrame() to see if this is
* valid). Otherwise, this will be the same as m_activeFrame, above
- *
- * private:
- * bool m_activeFound: Set to true if we found the target frame.
- * bool m_returnFound: Set to true if we found the target's return frame.
*/
class ControllerStackInfo
{
@@ -165,7 +165,6 @@ public:
bool m_targetFrameFound;
FrameInfo m_activeFrame;
- FrameInfo m_returnFrame;
CorDebugChainReason m_specialChainReason;
@@ -199,8 +198,9 @@ public:
//bool ControllerStackInfo::HasReturnFrame() Returns
// true if m_returnFrame is valid. Returns false
// if m_returnFrame is set to m_activeFrame
- bool HasReturnFrame() {LIMITED_METHOD_CONTRACT; return m_returnFound; }
+ bool HasReturnFrame(bool allowUnmanaged = false) {LIMITED_METHOD_CONTRACT; return m_returnFound && (allowUnmanaged || m_returnFrame.managed); }
+ FrameInfo& GetReturnFrame(bool allowUnmanaged = false) {LIMITED_METHOD_CONTRACT; return HasReturnFrame(allowUnmanaged) ? m_returnFrame : m_activeFrame; }
// This function "undoes" an unwind, i.e. it takes the active frame (the current frame)
// and sets it to be the return frame (the caller frame). Currently it is only used by
// the stepper to step out of an LCG method. See DebuggerStepper::DetectHandleLCGMethods()
@@ -213,6 +213,7 @@ private:
bool m_activeFound;
bool m_returnFound;
+ FrameInfo m_returnFrame;
// A ridiculous flag that is targetting a very narrow fix at issue 650903
// (4.5.1/Blue). This is set for the duration of a stackwalk designed to
diff --git a/src/debug/ee/frameinfo.cpp b/src/debug/ee/frameinfo.cpp
index 4c0ef2ba74..3efbddd140 100644
--- a/src/debug/ee/frameinfo.cpp
+++ b/src/debug/ee/frameinfo.cpp
@@ -585,7 +585,7 @@ void FrameInfo::AssertValid()
// Get the DJI associated w/ this frame. This is a convenience function.
// This is recommended over using MethodDescs because DJI's are version-aware.
//-----------------------------------------------------------------------------
-DebuggerJitInfo * FrameInfo::GetJitInfoFromFrame()
+DebuggerJitInfo * FrameInfo::GetJitInfoFromFrame() const
{
CONTRACTL
{
diff --git a/src/debug/ee/frameinfo.h b/src/debug/ee/frameinfo.h
index c4079029b8..990cf1b165 100644
--- a/src/debug/ee/frameinfo.h
+++ b/src/debug/ee/frameinfo.h
@@ -130,7 +130,7 @@ public:
// Does this FrameInfo represent a method frame? (aka a frameless frame)
// This may be combined w/ both StubFrames and ChainMarkers.
- bool HasMethodFrame() { return md != NULL && !internal; }
+ bool HasMethodFrame() const { return md != NULL && !internal; }
// Is this frame for a stub?
// This is mutually exclusive w/ Chain Markers.
@@ -138,14 +138,14 @@ public:
// M2U transition may have the Method for the Managed Wrapper for the unmanaged call.
// Stub frames map to internal frames on the RS. They use the same enum
// (CorDebugInternalFrameType) to represent the type of the frame.
- bool HasStubFrame() { return eStubFrameType != STUBFRAME_NONE; }
+ bool HasStubFrame() const { return eStubFrameType != STUBFRAME_NONE; }
// Does this FrameInfo mark the start of a new chain? (A Frame info may both
// start a chain and represent a method)
- bool HasChainMarker() { return chainReason != CHAIN_NONE; }
+ bool HasChainMarker() const { return chainReason != CHAIN_NONE; }
// Helper functions for retrieving the DJI and the DMI
- DebuggerJitInfo * GetJitInfoFromFrame();
+ DebuggerJitInfo * GetJitInfoFromFrame() const;
DebuggerMethodInfo * GetMethodInfoFromFrameOrThrow();
// Debug helper which nops in retail; and asserts invariants in debug.
diff --git a/src/inc/regdisp.h b/src/inc/regdisp.h
index 4a7e57e63d..e43bd0013e 100644
--- a/src/inc/regdisp.h
+++ b/src/inc/regdisp.h
@@ -48,7 +48,7 @@ struct REGDISPLAY_BASE {
TADDR ControlPC;
};
-inline PCODE GetControlPC(REGDISPLAY_BASE *pRD) {
+inline PCODE GetControlPC(const REGDISPLAY_BASE *pRD) {
LIMITED_METHOD_DAC_CONTRACT;
return (PCODE)(pRD->ControlPC);
}