All the things you describe are done automatically on program exit, even if the program is SIGKILL’ed. The kernel cleans up file descriptors, database transactions are rolled back automatically when the client disconnects (which it should be observed to be when the program exits and the kernel closes the connection as part of cleanup), and I’m not sure what you mean about mutexes, but if you mean in-memory ones, those don’t matter because the program is gone (if you mean like, file-based ones, those also should be implicitly unlocked by the kernel when the program exits, at least that’s how a good implementation is supposed to work, e.g. by writing the pid to the file or something.)
The whole of modern operating systems are already very familiar with the idea of programs not being able to exit gracefully, and there’s already a well understood category of things that happen automatically even if your program crashes ungracefully. Whole systems are designed around this (databases issuing rollbacks when the client disconnects, being a perfect example.) The best thing to do is embrace this and never, ever rely on a Drop trait being executed for correctness. Always assume you could be SIGKILLed at any time (which you always can. Someone can issue a kill -9, or you could get OOM killed, etc.)
I'm well aware of this and good that the option exists to bail out with abort instead.
But there are still cases where you would like to fsync your mmaps, print out a warning message or just make sure your #[should_panic] negative tests don't trigger false positives in your tooling (like leak detectors or GPU validators) or abort the whole test run.
It's not perfect by any means but it's better than potentially corrupting your data when a trivial assert fires or making negative tests spew warnings in ci runs.
It's very easy to opt out from, and I don't consider the price of panic handlers and unwinding very expensive for most use cases.
Right, sorry for the patronizing tone, I’m sure you know all this.
But I tend to lament the overall tendency for people to write cleanup code in general for this kind of thing. It’s one of those “lies programmers believe about X” kinds of scenarios. Your program will crash, and you will hit situations where your cleanup code will not run. You could get OOM killed. The user can force quit you. Hell, the power could go out! (Or the battery could go dead, etc.)
Nobody should ever write code that is only correct if they are given the opportunity to perfectly clean up after any failure that happens.
I see this all the time: CLI apps that trap Ctrl-C and tell you you can’t quit (yes I bloody well can, kill -9 is a thing), apps which don’t bother double checking that the files they left behind on a previous invocation are actually still used (stale pid files!!!), coworkers writing gobs of cleanup code that could have been avoided by simply doing nothing, etc etc.
The whole of modern operating systems are already very familiar with the idea of programs not being able to exit gracefully, and there’s already a well understood category of things that happen automatically even if your program crashes ungracefully. Whole systems are designed around this (databases issuing rollbacks when the client disconnects, being a perfect example.) The best thing to do is embrace this and never, ever rely on a Drop trait being executed for correctness. Always assume you could be SIGKILLed at any time (which you always can. Someone can issue a kill -9, or you could get OOM killed, etc.)