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

[x86/Linux] Port RtlVirtualUnwind#8911

Merged
janvorli merged 19 commits into
dotnet:masterfrom
parjong:fix/port_RtlVirtualUnwind
Jan 18, 2017
Merged

[x86/Linux] Port RtlVirtualUnwind#8911
janvorli merged 19 commits into
dotnet:masterfrom
parjong:fix/port_RtlVirtualUnwind

Conversation

@parjong
Copy link
Copy Markdown

@parjong parjong commented Jan 12, 2017

This commit (partially) ports RtlVirtualUnwind as a step to resolve #8887.

@parjong parjong changed the title [x86/Linux] port RtlVirtualUnwind [x86/Linux] port RtlVirtualUnwind - WIP Jan 12, 2017
@parjong
Copy link
Copy Markdown
Author

parjong commented Jan 12, 2017

We should merge this PR after merging #8889 as it depends on #8889. We could not build x86/Linux port if we merge this PR without merging #8889.

@parjong parjong changed the title [x86/Linux] port RtlVirtualUnwind - WIP [x86/Linux] port RtlVirtualUnwind (WIP) Jan 12, 2017
@parjong parjong changed the title [x86/Linux] port RtlVirtualUnwind (WIP) [x86/Linux] Port RtlVirtualUnwind (WIP) Jan 12, 2017
Comment thread src/inc/daccess.h Outdated
#endif

#ifdef _WIN64
#ifdef WIN64EXCEPTIONS
Copy link
Copy Markdown
Member

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.

Comment thread src/inc/regdisp.h Outdated

pRD->ctxPtrsOne.Lr = &pctx->Lr;
#elif defined(_TARGET_X86_) // _TARGET_ARM_
pRD->pEdi = &(pctx->Edi);
Copy link
Copy Markdown
Member

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.

@parjong
Copy link
Copy Markdown
Author

parjong commented Jan 17, 2017

@dotnet-bot test Windows_NT x64 Debug Build and Test please

@parjong
Copy link
Copy Markdown
Author

parjong commented Jan 17, 2017

@dotnet-bot test Windows_NT x86 Checked Build and Test please

@parjong parjong changed the title [x86/Linux] Port RtlVirtualUnwind (WIP) [x86/Linux] Port RtlVirtualUnwind Jan 17, 2017
Comment thread src/unwinder/i386/unwinder_i386.cpp Outdated
#undef CALLEE_SAVED_REGISTER
}

if ( rd.pEbp == NULL )
Copy link
Copy Markdown
Member

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?

Comment thread src/unwinder/i386/unwinder_i386.cpp Outdated
EECodeInfo codeInfo;
codeInfo.Init((PCODE) ControlPc);

if ( !UnwindStackFrame(&rd, &codeInfo, UpdateAllRegs, &codeManState, NULL) )
Copy link
Copy Markdown
Member

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?

Comment thread src/unwinder/i386/unwinder_i386.cpp Outdated

if ( !UnwindStackFrame(&rd, &codeInfo, UpdateAllRegs, &codeManState, NULL) )
{
return HRESULT_FROM_WIN32(ERROR_READ_FAULT);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A nit - wrong indentation

Comment thread src/unwinder/i386/unwinder_i386.cpp Outdated
)
{
*EstablisherFrame = ContextRecord->Esp;
*HandlerRoutine = NULL;
Copy link
Copy Markdown
Member

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?

Comment thread src/vm/eetwain.cpp
unsigned flags,
CodeManState *pState,
StackwalkCacheUnwindInfo *pUnwindInfo /* out-only, perf improvement */)
bool UnwindStackFrame(PREGDISPLAY pContext,
Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Author

@parjong parjong Jan 17, 2017

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).

Comment thread src/vm/eetwain.cpp Outdated
CodeManState *pState,
StackwalkCacheUnwindInfo *pUnwindInfo /* out-only, perf improvement */)
{
return UnwindStackFrame(pContext, pCodeInfo, flags, pState, pUnwindInfo);
Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Author

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.

Comment thread src/unwinder/i386/unwinder_i386.h Outdated
__deref_opt_out_opt PEXCEPTION_ROUTINE *HandlerRoutine);

private:
static HRESULT UnwindPrologue(
Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Member

@janvorli janvorli left a 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.

Comment thread src/vm/eetwain.cpp Outdated
CodeManState *pState,
StackwalkCacheUnwindInfo *pUnwindInfo /* out-only, perf improvement */)
{
return UnwindStackFrameEx(pContext, pCodeInfo, flags, pState, pUnwindInfo);
Copy link
Copy Markdown
Member

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?

Comment thread src/unwinder/i386/unwinder_i386.cpp Outdated
*EstablisherFrame = ContextRecord->Esp;
if (HandlerRoutine != NULL)
{
*HandlerRoutine = NULL;
Copy link
Copy Markdown
Member

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.

@parjong
Copy link
Copy Markdown
Author

parjong commented Jan 17, 2017

@janvorli Is there any issues with GC? I recently observed some randome failures on some GC testcases.

@parjong
Copy link
Copy Markdown
Author

parjong commented Jan 17, 2017

@dotnet-bot test Ubuntu x64 Checked Build and Test please

@janvorli
Copy link
Copy Markdown
Member

@parjong what were the failing tests?

@parjong
Copy link
Copy Markdown
Author

parjong commented Jan 18, 2017

@janvorli Oops, I restarted the test without recording failed tests. I'll let you know when I see it again.

@parjong
Copy link
Copy Markdown
Author

parjong commented Jan 18, 2017

@janvorli Ubuntu x64 Checked Build and Test failed with the following failure:

FAILED   - GC/Scenarios/DoublinkList/doublinkgen/doublinkgen.sh
               BEGIN EXECUTION
               /mnt/j/workspace/dotnet_coreclr/master/checked_ubuntu_tst_prtest/bin/tests/Windows_NT.x64.Checked/Tests/coreoverlay/corerun doublinkgen.exe
               Test should return with ExitCode 100 ...
               ./doublinkgen.sh: line 138:  7818 Aborted                 (core dumped) $_DebuggerFullPath "$CORE_ROOT/corerun" doublinkgen.exe $CLRTestExecutionArguments
               Expected: 100
               Actual: 134
               END EXECUTION - FAILED

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?

@janvorli
Copy link
Copy Markdown
Member

@parjong this test is known to be failing occassionaly. See #6574 .

Copy link
Copy Markdown
Member

@janvorli janvorli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@janvorli janvorli merged commit 0096973 into dotnet:master Jan 18, 2017
@parjong parjong deleted the fix/port_RtlVirtualUnwind branch January 18, 2017 22:14
@karelz karelz modified the milestone: 2.0.0 Aug 28, 2017
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
* [x86/Linux] (Partially) port RtlVirtualUnwind

* Rewrite x86 Unwinder using UnwindStackFrame

* Extract UnwindStackFrame from EECodeManager

* Port 'InlinedCallFrame::UpdateRegDisplay'


Commit migrated from dotnet/coreclr@0096973
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[x86/Linux] Support Simple Exception Catch

4 participants