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
Unhandled exception on Linux ignores Dispose #79155
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
/cc @janvorli |
I have investigated it and the reason is that Unix exception handling in case of unhandled exceptions doesn't run second pass and just fails fast with unhandled exception message. That is the reason why the finally generated by using is not called. It has been that way ever since .NET 1.0. While I don't remember why I have made it that way, it seems that one of the reason was diagnosability of such exceptions. The OS generated core dump contains the whole call stack and objects only in the first pass. In the second pass, the stack is unwound, so if the core dump was generated after the 2nd pass, it would not be possible to look at the whole program state at the time of the exception. |
This is real problem and I think serious one. Of course I cannot tell about all problems, but logging and caching is affected in my case. To make sure cache is consistent state, and logging wrote/sent all the data in And this is how I discovered this problem, I was struggling for some time why on earth my logger does not log anything while I have "flush" in Dispose so even in case of an exception it would be called. In theory. So this is the part of real problem. As for comment/remark I think it is serious because you cannot tell in advance what people keep in their Dispose, but they probably stick to what they learned:
From: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement The fundamentals of such importance should be kept, Linux, not Linux. IMHO. |
Btw, there are cases when the finally is not guaranteed to be executed even on Windows:
See https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-finally |
A workaround to your problem could be to never let exceptions become unhandled by having some top level catch. In fact, if you re-throw from such catch, you can even leave the exception being unhandled. It would just make sure the finallys are invoked. |
Couldn't the runtime automatically do that for the user? |
We cannot do that, because then you would lose the ability to diagnose the reasons for the crash from a crash dump / core. The stack would be unwound to the point of the rethrow, so all evidence of why the unhandled exception happened would be lost. I am trying to figure out how to keep the OS generated dump useful and still allow running the finally stuff, but so far I wasn't able to find a way to do that. If there was a way to trigger Unix core generation without exiting the process, it would solve the problem. But I don't think it is possible. |
|
|
If an implicit try
{
// ...
}
catch
{
throw;
} is a no-go, is it possible for the runtime to ensure that the |
This is another very practical use-case which does not leave any other possibility out of rebooting: |
Description
When you have unhandled exception which goes through
using
,Dispose
is ignored on Linux.Reproduction Steps
Run code with following content on Linux machine:
Expected behavior
Message "disposed" shown in terminal.
Actual behavior
No message.
Regression?
I don't know.
Known Workarounds
At top level wrap around everything in:
Configuration
openSUSE 15.3, x64. I see this bug when using dotnet 6.0 and 7.0.
I also tested it on Windows 10, x64 with dotnet 5.0, the program runs correctly (i.e. the message is displayed).
Other information
No response
The text was updated successfully, but these errors were encountered: