-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Closed
Labels
Milestone
Description
Test app:
[MethodImpl(MethodImplOptions.NoInlining)]
static void ThrowCatchAndRethrow(bool doCatch)
{
try
{
throw new Exception();
}
catch when (doCatch)
{
throw;
}
}
try
{
ThrowCatchAndRethrow(doCatch: true);
}
catch (Exception e)
{
Console.WriteLine("With rethrow:\n" + e.StackTrace);
Console.WriteLine($"Offset: 0x{new StackTrace(e).GetFrame(0).GetNativeOffset():X}");
}
try
{
ThrowCatchAndRethrow(doCatch: false);
}
catch (Exception e)
{
Console.WriteLine("\nNo rethrow:\n" + e.StackTrace);
Console.WriteLine($"Offset: 0x{new StackTrace(e).GetFrame(0).GetNativeOffset():X}");
}CoreCLR output:
> dotnet run -f net9.0
With rethrow:
at RyuJitReproduction.Program.ThrowCatchAndRethrow(Boolean doCatch) in C:\Users\Accretion\source\dotnet\RyuJit\RyuJitReproduction\Program.cs:line 77
at RyuJitReproduction.Program.Main() in C:\Users\Accretion\source\dotnet\RyuJit\RyuJitReproduction\Program.cs:line 94
Offset: 0x54
No rethrow:
at RyuJitReproduction.Program.ThrowCatchAndRethrow(Boolean doCatch) in C:\Users\Accretion\source\dotnet\RyuJit\RyuJitReproduction\Program.cs:line 77
at RyuJitReproduction.Program.Main() in C:\Users\Accretion\source\dotnet\RyuJit\RyuJitReproduction\Program.cs:line 104
Offset: 0x54
Note how the native offsets are equal, and so are the line numbers.
NativeAOT output:
> dotnet publish -f net9.0 /p:PublishAot=true && .\bin\Release\net9.0\win-x64\publish\RyuJitReproduction.exe
With rethrow:
at RyuJitReproduction.Program.ThrowCatchAndRethrow(Boolean) + 0x50
at RyuJitReproduction.Program.Main() + 0x55
Offset: 0x50
No rethrow:
at RyuJitReproduction.Program.ThrowCatchAndRethrow(Boolean) + 0x2d
at RyuJitReproduction.Program.Main() + 0x5e
Offset: 0x2D
Note how different IPs are reported (the IP of the throw is switched to the IP of the rethrow).
See also ThrowStatementDoesNotResetExceptionStackLineOtherMethod, which suggests that this difference is a NativeAOT bug.
This is the reason for the difference:
runtime/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Exception.NativeAot.cs
Lines 66 to 73 in c4792a2
| else if (isFirstRethrowFrame) | |
| { | |
| // For the first frame after rethrow, we replace the last entry in the stack trace with the IP | |
| // of the rethrow. This is overwriting the IP of where control left the corresponding try | |
| // region for the catch that is rethrowing. | |
| _corDbgStackTrace[_idxFirstFreeStackTraceEntry - 1] = IP; | |
| return; | |
| } |
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
No status