-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Preserve last error for patchpoint helpers #75922
Conversation
In stress modes (and eventually perhaps in normal uses) the jit may insert patchpoint helper calls in regions where last error is live. So the helpers need to preserve last error. Because some invocations of the helpers may transition to OSR methods instead of returning, we can't use the normal macros for this. Fixes dotnet#75828.
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsIn stress modes (and eventually perhaps in normal uses) the jit may insert patchpoint helper calls in regions where last error is live. So the helpers need to preserve last error. Because some invocations of the helpers may transition to OSR methods instead of returning, we can't use the normal macros for this. Fixes #75828.
|
@jakobbotsch PTAL Seems like EnC could hit this issue too? |
src/coreclr/vm/jithelpers.cpp
Outdated
@@ -4916,6 +4916,9 @@ HCIMPLEND | |||
|
|||
void JIT_Patchpoint(int* counter, int ilOffset) | |||
{ | |||
// BEGIN_PRESERVE_LAST_ERROR; | |||
DWORD __dwLastError = ::GetLastError(); |
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.
DWORD __dwLastError = ::GetLastError(); | |
DWORD dwLastError = ::GetLastError(); |
src/coreclr/vm/jithelpers.cpp
Outdated
@@ -5205,6 +5220,9 @@ void JIT_Patchpoint(int* counter, int ilOffset) | |||
// | |||
void JIT_PartialCompilationPatchpoint(int ilOffset) | |||
{ | |||
// BEGIN_PRESERVE_LAST_ERROR; | |||
DWORD __dwLastError = ::GetLastError(); |
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.
DWORD __dwLastError = ::GetLastError(); | |
DWORD dwLastError = ::GetLastError(); |
I do not see any obvious problem. EnC patch runs inside debugger step handler that is preserving last error: runtime/src/coreclr/vm/exceptionhandling.cpp Line 857 in 5384105
|
OSX seems to have some networking issues:
|
Yeah, almost every PR today has failed most mac legs because of that. @MattGal is investigating. |
The "normal" channels are being a bit slow but I have confirmed they're aware of the throttling problem and are trying to identify the cause presently. |
Is this .NET 7 backport candidate? (Intermittent data corruption caused by OSR.) |
I don't know if we can hit this with normal OSR. The failure above is from a stress mode that places patchpoints in randomly selected blocks where the stack is empty, whereas OSR normally will only place patchpoints at blocks that are the start or end of a loop. I'll spend some time today trying to work up a case; seems like the "end of loop" patchpoint (which is the default placement) might be a place we could hit this normally. |
I would expect that something like this can hit this reliably:
|
Yes, thanks. Repro is simple and deterministic; the failure happens in Tier0 code once it has invoked the patchpoint helper. Will add a test case. |
For Linxu arm64 NAOT: msbuild crashed during restore:
Similar perhaps to #43826 but that issue is quite old. |
@jeffschwMSFT @JulieLeeMSFT we should consider porting this to 7.0. |
@AndyAyersMS in what cases (beyond stress modes) do we anticipate that this may occur? |
This PR has a simple test case that fails without stress -- the value of last error will not be preserved across loops. |
In a more real-world situation, the long-running for-loop in the test can be some kind of interop marshalling code. |
/backport to release/7.0 |
Started backporting to release/7.0: https://github.com/dotnet/runtime/actions/runs/3130148038 |
In stress modes (and eventually perhaps in normal uses) the jit may insert patchpoint helper calls in regions where last error is live. So the helpers need to preserve last error.
Because some invocations of the helpers may transition to OSR methods instead of returning, we can't use the normal macros for this.
Fixes #75828.