[clr-interp] Add initial CoreCLR interpreter func-eval support#126576
[clr-interp] Add initial CoreCLR interpreter func-eval support#126576matouskozak wants to merge 5 commits intodotnet:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds initial debugger func-eval support when the target thread is stopped in CoreCLR interpreter code, by avoiding native-context hijacking and instead running queued evals from the interpreter breakpoint path.
Changes:
- Adds a pending func-eval slot to the interpreter thread context and triggers execution after the breakpoint debugger callback returns.
- Extends
DebugInterface/Debuggerwith an interpreter-specific hook to execute pending evals. - Adjusts
FuncEvalSetup/DebuggerEvalinitialization to skip native-only setup (e.g., executable breakpoint segment allocation, SP alignment checks) for interpreter evals.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/vm/interpexec.h | Adds InterpThreadContext::m_pPendingFuncEval storage for interpreter-thread func-evals. |
| src/coreclr/vm/interpexec.cpp | Executes pending interpreter func-evals from the INTOP_BREAKPOINT handler using a synthetic filter context. |
| src/coreclr/vm/dbginterface.h | Adds ExecutePendingInterpreterFuncEval(Thread*) to the debug interface under FEATURE_INTERPRETER. |
| src/coreclr/debug/ee/debugger.h | Declares the Debugger implementation of ExecutePendingInterpreterFuncEval. |
| src/coreclr/debug/ee/debugger.cpp | Implements pending-eval execution and updates FuncEvalSetup/DebuggerEval to support interpreter eval flow. |
src/coreclr/vm/interpexec.cpp
Outdated
| // FuncEvalHijackWorker needs it to identify the thread as stopped in managed | ||
| // code and at a GC-safe point. Set a synthetic filter context here so that | ||
| // nested/subsequent func evals can pass the safety checks in FuncEvalSetup. | ||
| if (pThreadContext->m_pPendingFuncEval != NULL && g_pDebugInterface != NULL) |
There was a problem hiding this comment.
Can this be done inside InterpBreakpoint?
CONTEXT is a very large structure. We do not want to add it to the main interpreter executor loop native frame. It would likely regress performance of the interpreter executor loop.
There was a problem hiding this comment.
That's a good point, we can keep everything in the InterpBreakpoint method.
|
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
| // stopped in interpreter code, FuncEvalSetup stores the DebuggerEval* here instead | ||
| // of hijacking the native CPU context (which doesn't work for interpreter threads). | ||
| // The INTOP_BREAKPOINT handler checks this after the debugger callback returns. | ||
| void *m_pPendingFuncEval; // DebuggerEval* (void* to avoid header dependency) |
There was a problem hiding this comment.
Could we do a forward declaration of DebuggerEval to keep this strongly typed without the header dependency?
Description
This adds initial func-eval support for threads stopped in CoreCLR interpreter code.
Testing:
Future Work
#125959