-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
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
Exception during close causes hang at "Dumping the backtrace." #82102
Comments
It appears as though the second exception is because the
Edit: I've learned it's actually because the backtrace method godot uses is not signal-safe. Signals are asynchronous and cause virtually all interactions with existing main-memory objects to be undefined. The freeze is caused by the non-signal-safe code causing a secondary fatal signal during crash handling. More details below. |
As a workaround, you can disable the crash handler by running Godot with the |
I've learned that signal is heavily implementation specific. According to the cppreference docs:
This means that we won't know if further exceptions during crash handling will be ignored, cause loops, lockups, or crashes since it's completely implementation specific. It also states
I'm not sure if sigaction is a good fit for godot, since godot is multi-platform and sigaction is not. And it's nice keeping the crash handlers somewhat similar in design when possible. So now for my proposed solution: a very simple fix is to enforce the behavior of signal by starting the crash handler with static void handle_crash(int sig) {
signal(SIGSEGV, SIG_DFL);
signal(SIGFPE, SIG_DFL);
signal(SIGILL, SIG_DFL);
... This prevents further fatal errors from initiating patty-cake with the kernel for most implementations. The trade-off being that we still won't know if the implementation is currently ignoring any of the signals. I think making it work for all implementations would require a reassessment for using sigaction. Regardless, this change should make the crash handlers more sane without being complicated. Tested it and it works okay: Pull request to follow soon. |
Godot version
v4.2.dev.mono.custom_build.fe5b1c8d4, v4.1.1
System information
Arch linux, AMD Ryzen 7 5800X3D x86_64, Radeon RX 6950 XT
Issue description
When closing godot-mono via a
GetTree().Quit()
or by alt-f4ing, occasionally (once every five runs), a SIGSEV exception gets thrown (caught via debugger):No big deal, you'd think the crash handler would catch it and give a backtrace. But it gets to here... then immediately throws another SIGSEV exception (also caught via debugger):
From here it just permanently hangs at "Dumping the backtrace", taking 100% CPU and being unresponsive. I'm figuring the exception handler is just looping-- my debugger can't follow it, something causes my debugger to detach when it starts looping.
Happens on stable as well, I think during cleanup, some of the machinery that the exception handler uses is cleaned up already so it fails to give a stack trace. I'm not sure though.
Forces me to close it via a TERM or KILL signal via my task manager, which is very hurtful to my iteration speeds.
Steps to reproduce
Repeatedly open the project while mashing the Esc key, it will hang when it fails.
The crash was surprisingly consistent, yet random. Sometimes taking 10 tries or so.
I couldn't find a 100% consistent way to crash. I also couldn't get the crash to happen on a blank project, so I must be doing something strange in the project that I've included. I shrunk it down the best I could.
Minimal reproduction project
It was 45mb, so it didn't fit on github, here's a few mirrors:
https://drive.google.com/file/d/1OIefwglUPwOiieQhzDBxWgs6vwCWJ-QS/view?usp=sharing
https://cdn.discordapp.com/attachments/437504631577509899/1154695790212689971/MRP.zip
The text was updated successfully, but these errors were encountered: