-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Conversation
@@ -2393,13 +2393,13 @@ typedef DPTR(IMAGE_TLS_DIRECTORY) PTR_IMAGE_TLS_DIRECTORY; | |||
#include <xclrdata.h> | |||
#endif | |||
|
|||
#ifdef _WIN64 | |||
#ifdef WIN64EXCEPTIONS |
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.
This doesn't seem right. The WIN64EXCEPTIONS are defined for TARGET_ARM too, so this change would create duplicite typedefs. So I wonder how come the CI build succeeded. Maybe the WIN64EXCEPTIONS is not defined in this file.
@@ -435,10 +435,20 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC | |||
|
|||
pRD->ctxPtrsOne.Lr = &pctx->Lr; | |||
#elif defined(_TARGET_X86_) // _TARGET_ARM_ | |||
pRD->pEdi = &(pctx->Edi); |
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.
This won't work for the stack walking with WIN64EXCEPTIONS. When WIN64EXCEPTIONS are defined, the stack walking uses pCurrentContextPointers and doesn't know anything about the pEsi, pEbx etc. So while the unwinder would store the context pointers in these, the pCurrentContext would always just point to the context structure instead of the real location where the register value came from.
What I believe you need to do instead is to remove the setting of the pEsi etc here and then in the OOPStackUnwinderX86::VirtualUnwind set the pRD->pEsi etc to the corresponding values from the pCurrentContext before calling the CodeManager::UnwindStackFrame. And right after calling them, copy them from the RegDisplay::pEsi etc to the corresponding members of the pCurrentContext.
Also, you need to do that only for EDI, ESI, EBX and EBP. The CodeManager::UnwindStackFrame doesn't update any others. These are the only callee saved registers.
Also, the CopyRegDisplay needs to be modified so that it uses the code path that's now for non-x86 targets for x86 on Linux too.
@dotnet-bot test Windows_NT x64 Debug Build and Test please |
@dotnet-bot test Windows_NT x86 Checked Build and Test please |
89c0e4d
to
1496247
Compare
#undef CALLEE_SAVED_REGISTER | ||
} | ||
|
||
if ( rd.pEbp == NULL ) |
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.
A nit - can you please remove extra space after (
and before )
here?
EECodeInfo codeInfo; | ||
codeInfo.Init((PCODE) ControlPc); | ||
|
||
if ( !UnwindStackFrame(&rd, &codeInfo, UpdateAllRegs, &codeManState, NULL) ) |
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.
A nit - can you please remove extra space after (
and before )
here?
|
||
if ( !UnwindStackFrame(&rd, &codeInfo, UpdateAllRegs, &codeManState, NULL) ) | ||
{ | ||
return HRESULT_FROM_WIN32(ERROR_READ_FAULT); |
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.
A nit - wrong indentation
) | ||
{ | ||
*EstablisherFrame = ContextRecord->Esp; | ||
*HandlerRoutine = NULL; |
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 HandlerRoutine is an optional pointer, based on the annotation (__deref_opt_out_opt). Can you please wrap the assignment in check it is not NULL?
unsigned flags, | ||
CodeManState *pState, | ||
StackwalkCacheUnwindInfo *pUnwindInfo /* out-only, perf improvement */) | ||
bool UnwindStackFrame(PREGDISPLAY pContext, |
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 am not sure I understand why you have moved this function out of the EECodeManager and then just call it from there.
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.
Stack walker directly calls EECodeManager::UnwindStackFrame
, but this implementation does not update WIN64EXCEPTIONS
-related fields (which results in unwind failure).
CodeManState *pState, | ||
StackwalkCacheUnwindInfo *pUnwindInfo /* out-only, perf improvement */) | ||
{ | ||
return UnwindStackFrame(pContext, pCodeInfo, flags, pState, pUnwindInfo); |
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 believe this creates an infinite loop, since it would call itself instead of the function.
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.
You're right... I'll fix it.
__deref_opt_out_opt PEXCEPTION_ROUTINE *HandlerRoutine); | ||
|
||
private: | ||
static HRESULT UnwindPrologue( |
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.
It looks like the UnwindPrologue and GetEstabliserFrame can be removed since they are not even implemented.
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.
These are the last requests to change. We can merge it after that.
CodeManState *pState, | ||
StackwalkCacheUnwindInfo *pUnwindInfo /* out-only, perf improvement */) | ||
{ | ||
return UnwindStackFrameEx(pContext, pCodeInfo, flags, pState, pUnwindInfo); |
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 "Ex" seems little strange since the standalone function is not an extended version. You could have kept the same name and just classify it by "::" to indicate that the global version should be called here:
return ::UnwindStackFrame(pContext, pCodeInfo, flags, pState, pUnwindInfo);
Would you mind changing it that way?
*EstablisherFrame = ContextRecord->Esp; | ||
if (HandlerRoutine != NULL) | ||
{ | ||
*HandlerRoutine = NULL; |
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.
One last nit - can you please normalize the spacing in this function? What I mean is to ensure that there is just one space at each side of the =
and also one space between a type and variable in variable declarations.
@janvorli Is there any issues with GC? I recently observed some randome failures on some GC testcases. |
@dotnet-bot test Ubuntu x64 Checked Build and Test please |
@parjong what were the failing tests? |
@janvorli Oops, I restarted the test without recording failed tests. I'll let you know when I see it again. |
@janvorli Ubuntu x64 Checked Build and Test failed with the following failure:
It seems that the current PR should not affect x64/Linux port, but x64/Linux port shows test failure. Could you let me know if you have any clue? |
@parjong this test is known to be failing occassionaly. See #6574 . |
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.
LGTM, thank you!
* [x86/Linux] (Partially) port RtlVirtualUnwind * Rewrite x86 Unwinder using UnwindStackFrame * Extract UnwindStackFrame from EECodeManager * Port 'InlinedCallFrame::UpdateRegDisplay' Commit migrated from dotnet/coreclr@0096973
This commit (partially) ports RtlVirtualUnwind as a step to resolve #8887.