-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Debugger fixes for the Windows X86 EH Funclets model #115630
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
73c21b5
ca2f490
3708d1a
1e4ecc8
c4710f0
7c14b4e
b860621
d5aa015
d32e3d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -211,7 +211,7 @@ RtlpGetFunctionEndAddress ( | |
| _In_ TADDR ImageBase | ||
| ) | ||
| { | ||
| PUNWIND_INFO pUnwindInfo = (PUNWIND_INFO)(ImageBase + FunctionEntry->UnwindData); | ||
| DPTR(UNWIND_INFO) pUnwindInfo = dac_cast<DPTR(UNWIND_INFO)>(ImageBase + FunctionEntry->UnwindData); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ouch :) |
||
|
|
||
| return FunctionEntry->BeginAddress + pUnwindInfo->FunctionLength; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -1578,6 +1578,15 @@ size_t GCInfo::gcInfoBlockHdrSave( | |||||
| assert(header->epilogCount <= 1); | ||||||
| } | ||||||
| #endif | ||||||
| if (compiler->UsesFunclets() && compiler->info.compFlags & CORINFO_FLG_SYNCH && compiler->opts.compDbgEnC) | ||||||
|
||||||
| if (compiler->UsesFunclets() && compiler->info.compFlags & CORINFO_FLG_SYNCH && compiler->opts.compDbgEnC) | |
| if (compiler->UsesFunclets() && compiler->info.compFlags & CORINFO_FLG_SYNCH) |
We need this information even for non-EnC to get position of generic parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reference, this is exposed with the Pri1 tests with DOTNET_GCStress=0x3 in JIT\Generics\Fields\getclassfrommethodparam\getclassfrommethodparam.dll.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've addressed this issue as well as an issue where the method is both synchronized and has a stack allocation in it.
davidwrighton marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Copilot
AI
May 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding a comment to explain the rationale behind using the literal offsets (1 and 2) for syncStartOffset and syncEndOffset to improve clarity and future maintainability.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to set syncEndOffset to 1 as well? That way the region becomes effectively empty and invalid. It would make it easier to detect this abuse of the encoding in diagnostic tools for both FEATURE_EH_FUNCLETS and legacy builds.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a decent point. I don't think we have any diagnostic tools that care, but data that is patently invalid would be easier to check for. As I recall, I'd need to relax an assert or two, but that's no big deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Looks like it was just the one assert which was a problem.
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -653,6 +653,15 @@ inline size_t GetSizeOfFrameHeaderForEnC(hdrInfo * info) | |||||||||||||
| { | ||||||||||||||
| WRAPPER_NO_CONTRACT; | ||||||||||||||
|
|
||||||||||||||
| #ifdef FEATURE_EH_FUNCLETS | ||||||||||||||
| _ASSERTE(info->ebpFrame); | ||||||||||||||
| unsigned position = info->savedRegsCountExclFP + | ||||||||||||||
| info->localloc + | ||||||||||||||
| info->genericsContext + // For CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG | ||||||||||||||
| ((info->syncStartOffset != INVALID_SYNC_OFFSET) ? 1 : 0) // Is this method synchronized | ||||||||||||||
| + 1; // for ebpFrame | ||||||||||||||
|
Comment on lines
+677
to
+679
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Let's use an order that's closer to the reality. We also need to apply the same fix to inline
size_t GetParamTypeArgOffset(hdrInfo * info)
{
LIMITED_METHOD_DAC_CONTRACT;
_ASSERTE((info->genericsContext || info->handlers) && info->ebpFrame);
#ifdef FEATURE_EH_FUNCLETS
unsigned position = info->savedRegsCountExclFP +
info->localloc +
((info->syncStartOffset != INVALID_SYNC_OFFSET) ? 1 : 0) + // Is this method synchronized
1; // For CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG
#else
unsigned position = info->savedRegsCountExclFP +
info->localloc +
1; // For CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG
#endif
return position * sizeof(TADDR);
} |
||||||||||||||
| return position * sizeof(TADDR); | ||||||||||||||
| #else | ||||||||||||||
| // See comment above Compiler::lvaAssignFrameOffsets() in src\jit\il\lclVars.cpp | ||||||||||||||
| // for frame layout | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -664,6 +673,7 @@ inline size_t GetSizeOfFrameHeaderForEnC(hdrInfo * info) | |||||||||||||
| // to get the total size of the header. | ||||||||||||||
| return sizeof(TADDR) + | ||||||||||||||
| GetEndShadowSPSlotsOffset(info, MAX_EnC_HANDLER_NESTING_LEVEL); | ||||||||||||||
| #endif // FEATURE_EH_FUNCLETS | ||||||||||||||
| } | ||||||||||||||
| #endif // FEATURE_NATIVEAOT | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just out of curiosity for me - why is this branch only taken on non-x86? I'd expect this to be a funclet path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The x86 unwinder continues to have a subtly different set of interactions with the rest of the codebase compared to the other architectures. Its... much closer than it was before, but the frame pointer concepts are somewhat different, and when I wrote this it appeared that it is related to the nature of X86 codegen where the sp moves during code execution in a frame, and how the unwinder updates somewhat different structures as it runs.