Uh oh!
There was an error while loading. Please reload this page.
[NativeAOT] correctly initalize CONTEXT before failing fast - #81010
Conversation
ghost
commented
Jan 23, 2023
Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas Issue DetailsShort ExplanationBasically the Long ExplanationConsider this program: usingSystem;usingSystem.Globalization;staticclassProgram{staticvoidFillStack(bytevalue){Span<byte>bytes=stackallocbyte[1024*16];bytes.Fill(value);}staticvoidMain(string[]args){if(args.Length!=0){bytefillValue=byte.Parse(args[0],NumberStyles.HexNumber);AppDomain.CurrentDomain.UnhandledException+=(_,_)=>FillStack(fillValue);}thrownewException();}}When run on Windows, the last thing it does is call If you pass That's less than ideal as it does not directly point at the faulting function. If you pass After this PR is merged, the call stack correctly points at the faulting function: TODO before merging:
I won't bother with x86 since it not currently supported by NativeAOT.
|
jkotas
commented
Jan 23, 2023
I do not think we want to grow |
68e537e to
667caacCompareAustinWise
commented
Jan 27, 2023
I did not bother getting the segment registers when running on non-Windows, as the only use of the |
In such case there is no need for a |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Vladimir Sadov <vsadov@microsoft.com>
AustinWise
commented
Jan 31, 2023
FYI, this problem reproduces with .NET 7.0.2 on Windows 11 22H2. So it should be considered for servicing to the .NET 7 branch. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
AustinWise
commented
Feb 1, 2023
Test failure looks like #75244. It the "coreclr Pri0 Runtime Tests Run windows x86 checked" job that failed, so presumably that's unrelated to this NativeAOT change. |
jkotas
commented
Feb 6, 2023
I am not able to reproduce it. What is the program that you were able to reproduce it with? |
I made a GitHub repo with the reproduction program and a script that builds and runs: https://github.com/AustinWise/dotnet-81010 Also included in the readme is the exact versions of software used. |
jkotas
commented
Feb 8, 2023
Thanks for great repro! |
jkotas
commented
Feb 8, 2023
/backport to release/7.0 |
Started backporting to release/7.0: https://github.com/dotnet/runtime/actions/runs/4127325824 |
Short Explanation
Basically the
CONTEXTstructure is not being initalized properly before callingRaiseFailFastException.Long Explanation
Consider this program:
On NativeAOT on Windows, the last act of a process that throws an unhanded exception is to call
RaiseFailFastExceptionhere. The instruction pointer andCONTEXTstructure passed toRaiseFailFastExceptionpoint at the function that raised the unhanded exception. If you have a debugger like Visual Studio attached after whenRaiseFailFastExceptionis called, you will see a call stack pointing to the faulting function.Depending on what argument you pass to the program, you get different call stacks.
If you pass
0you get:That's less than ideal as it does not directly point at the faulting function.
If you pass
ffyou get garbage:After this PR is merged, the call stack correctly points at the faulting function:
TODO before merging:
AMD64: captureCS,SS, andRFLAGSintoPAL_LIMITED_CONTEXTwhen throwing and exceptionAMD64: restoreCS,SS, andRFLAGSinRhpCopyContextFromExInfoRhpCopyContextFromExInfo, capture theCSandSSsegment registers from the current thread and stuff them into theCONTEXT.