Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 30583ce

Browse files
authored
Fix step with stackalloc (#27246) (#27351)
* 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
1 parent 7a8e08c commit 30583ce

File tree

8 files changed

+77
-97
lines changed

8 files changed

+77
-97
lines changed

src/debug/di/module.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1550,7 +1550,8 @@ HRESULT CordbModule::GetFunctionFromToken(mdMethodDef token,
15501550
RSLockHolder lockHolder(GetProcess()->GetProcessLock());
15511551

15521552
// Check token is valid.
1553-
if ((token == mdMethodDefNil) ||
1553+
if ((token == mdMethodDefNil) ||
1554+
(TypeFromToken(token) != mdtMethodDef) ||
15541555
(!GetMetaDataImporter()->IsValidToken(token)))
15551556
{
15561557
ThrowHR(E_INVALIDARG);

src/debug/di/rsfunction.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ CordbFunction::CordbFunction(CordbModule * m,
4949
m_methodSigParserCached = SigParser(NULL, 0);
5050

5151
_ASSERTE(enCVersion >= CorDB_DEFAULT_ENC_FUNCTION_VERSION);
52+
_ASSERTE(TypeFromToken(m_MDToken) == mdtMethodDef);
5253
}
5354

5455

src/debug/di/rspriv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5537,7 +5537,7 @@ class CordbFunction : public CordbBase,
55375537
RSSmartPtr<CordbNativeCode> m_nativeCode;
55385538

55395539
// Metadata Token for the IL function. Scoped to m_module.
5540-
mdMethodDef m_MDToken;
5540+
const mdMethodDef m_MDToken;
55415541

55425542
// EnC version number of this instance
55435543
SIZE_T m_dwEnCVersionNumber;

src/debug/ee/controller.cpp

Lines changed: 60 additions & 83 deletions
Large diffs are not rendered by default.

src/debug/ee/controller.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,15 @@ class StackTraceTicket
140140
* FrameInfo m_activeFrame: A FrameInfo
141141
* describing the target frame. This should always be valid after a
142142
* call to GetStackInfo.
143+
*
144+
* private:
145+
* bool m_activeFound: Set to true if we found the target frame.
146+
* bool m_returnFound: Set to true if we found the target's return frame.
143147
*
144148
* FrameInfo m_returnFrame: A FrameInfo
145149
* describing the frame above the target frame, if target's
146150
* return frame were found (call HasReturnFrame() to see if this is
147151
* valid). Otherwise, this will be the same as m_activeFrame, above
148-
*
149-
* private:
150-
* bool m_activeFound: Set to true if we found the target frame.
151-
* bool m_returnFound: Set to true if we found the target's return frame.
152152
*/
153153
class ControllerStackInfo
154154
{
@@ -165,7 +165,6 @@ class ControllerStackInfo
165165
bool m_targetFrameFound;
166166

167167
FrameInfo m_activeFrame;
168-
FrameInfo m_returnFrame;
169168

170169
CorDebugChainReason m_specialChainReason;
171170

@@ -199,8 +198,9 @@ class ControllerStackInfo
199198
//bool ControllerStackInfo::HasReturnFrame() Returns
200199
// true if m_returnFrame is valid. Returns false
201200
// if m_returnFrame is set to m_activeFrame
202-
bool HasReturnFrame() {LIMITED_METHOD_CONTRACT; return m_returnFound; }
201+
bool HasReturnFrame(bool allowUnmanaged = false) {LIMITED_METHOD_CONTRACT; return m_returnFound && (allowUnmanaged || m_returnFrame.managed); }
203202

203+
FrameInfo& GetReturnFrame(bool allowUnmanaged = false) {LIMITED_METHOD_CONTRACT; return HasReturnFrame(allowUnmanaged) ? m_returnFrame : m_activeFrame; }
204204
// This function "undoes" an unwind, i.e. it takes the active frame (the current frame)
205205
// and sets it to be the return frame (the caller frame). Currently it is only used by
206206
// the stepper to step out of an LCG method. See DebuggerStepper::DetectHandleLCGMethods()
@@ -213,6 +213,7 @@ class ControllerStackInfo
213213

214214
bool m_activeFound;
215215
bool m_returnFound;
216+
FrameInfo m_returnFrame;
216217

217218
// A ridiculous flag that is targetting a very narrow fix at issue 650903
218219
// (4.5.1/Blue). This is set for the duration of a stackwalk designed to

src/debug/ee/frameinfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ void FrameInfo::AssertValid()
585585
// Get the DJI associated w/ this frame. This is a convenience function.
586586
// This is recommended over using MethodDescs because DJI's are version-aware.
587587
//-----------------------------------------------------------------------------
588-
DebuggerJitInfo * FrameInfo::GetJitInfoFromFrame()
588+
DebuggerJitInfo * FrameInfo::GetJitInfoFromFrame() const
589589
{
590590
CONTRACTL
591591
{

src/debug/ee/frameinfo.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,22 +130,22 @@ struct FrameInfo
130130

131131
// Does this FrameInfo represent a method frame? (aka a frameless frame)
132132
// This may be combined w/ both StubFrames and ChainMarkers.
133-
bool HasMethodFrame() { return md != NULL && !internal; }
133+
bool HasMethodFrame() const { return md != NULL && !internal; }
134134

135135
// Is this frame for a stub?
136136
// This is mutually exclusive w/ Chain Markers.
137137
// StubFrames may also have a method frame as a "hint". Ex, a stub frame for a
138138
// M2U transition may have the Method for the Managed Wrapper for the unmanaged call.
139139
// Stub frames map to internal frames on the RS. They use the same enum
140140
// (CorDebugInternalFrameType) to represent the type of the frame.
141-
bool HasStubFrame() { return eStubFrameType != STUBFRAME_NONE; }
141+
bool HasStubFrame() const { return eStubFrameType != STUBFRAME_NONE; }
142142

143143
// Does this FrameInfo mark the start of a new chain? (A Frame info may both
144144
// start a chain and represent a method)
145-
bool HasChainMarker() { return chainReason != CHAIN_NONE; }
145+
bool HasChainMarker() const { return chainReason != CHAIN_NONE; }
146146

147147
// Helper functions for retrieving the DJI and the DMI
148-
DebuggerJitInfo * GetJitInfoFromFrame();
148+
DebuggerJitInfo * GetJitInfoFromFrame() const;
149149
DebuggerMethodInfo * GetMethodInfoFromFrameOrThrow();
150150

151151
// Debug helper which nops in retail; and asserts invariants in debug.

src/inc/regdisp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ struct REGDISPLAY_BASE {
4848
TADDR ControlPC;
4949
};
5050

51-
inline PCODE GetControlPC(REGDISPLAY_BASE *pRD) {
51+
inline PCODE GetControlPC(const REGDISPLAY_BASE *pRD) {
5252
LIMITED_METHOD_DAC_CONTRACT;
5353
return (PCODE)(pRD->ControlPC);
5454
}

0 commit comments

Comments
 (0)