4 ms·
> C++ static initialization order fiasco This is a good one but IMO better still is the destructors-on-dlclose fiasco. Seems like different systems have wildl
by wyldfire 5y ago
> C++ static initialization order fiasco
This is a good one but IMO better still is the destructors-on-dlclose fiasco. Seems like different systems have wildly different interpretations about how to handle this condition, and it's not really covered by a standard.
See musl, glibc, BSD as examples.
- dataflow 5y agoI was curious how Windows handled process teardown not too long ago, dug into it, and realized it just kills the process instantly. Which seems both brilliant and awful at the same time. Any idea how other systems handle teardown?
- david2ndaccount 5y agoYour application needs to be robust in the face of the power going out, being OOM killed and other non-orderly shutdowns. Given that, there’s no point in using a different mechanism for an orderly shutdown. Just exit, don’t run destructors, they’re a waste of time.
- dataflow 5y agoEverything needs to be perfect, so there's no point in accommodating anything less than perfect?
- 112233 5y agoIs it somehow possible to tell gcc/llvm “This program will never terminate normally. Please don’t bother with static dtors” ? Or at least somehow purge all that code when linking?
- cozzyd 5y agoStrip .fini ?
- kccqzy 5y agoman 3 exit The exit() function causes normal process termination and the least significant byte of status (i.e., status & 0xFF) is returned to the parent (see wait(2)). All functions registered with atexit(3) and on_exit(3) are called, in the reverse order of their registration. (It is possible for one of these functions to use atexit(3) or on_exit(3) to register an additional function to be executed during exit processing; the new registration is added to the front of the list of functions that remain to be called.) If one of these functions does not return (e.g., it calls _exit(2), or kills itself with a signal), then none of the remaining functions is called, and further exit processing (in particular, flushing of stdio(3) streams) is abandoned. If a function has been registered multiple times using atexit(3) or on_exit(3), then it is called as many times as it was registered. All open stdio(3) streams are flushed and closed. Files created by tmpfile(3) are removed. These all happen inside userspace. The kernel doesn't necessarily know it's exiting. It's _exit() that tells the kernel the process is exiting. The kernel then does some more processing like closing file descriptors. man 2 _exit _exit() terminates the calling process "immediately". Any open file descriptors belonging to the process are closed. Any children of the process are inherited by init(1) (or by the nearest "subreaper" process as defined through the use of the prctl(2) PR_SET_CHILD_SUBREAPER operation). The process's parent is sent a SIGCHLD signal. The value status & 0xFF is returned to the parent process as the process's exit status, and can be collected by the parent using one of the wait(2) family of calls.
- yakubin 5y agoWhy awful?
- ahartmetz 5y agoReminds me of an "interesting" but mostly useless idea I had... to speed up orderly process termination on Linux, monkeypatch free() (I'm thonking of messing with symbol resolution, better than adding a conditional in the hot path) to do nothing during exit. Problem is, it's already quite fast and no one cares. There are some potential problems with that but why attack them if no one needs the feature?
- qiqitori 5y agoFunny, I have an unsolved bug sort of in this area that I have never managed to reproduce. (I don't use C++ normally so that may hinder my efforts a bit? I'll try and read the article to see if that helps a bit.) I have exactly one core dump from a colleague who managed to reproduce the issue once after thousands of power cycles, and never again even after doing another 100,000 power cycles. The core file indicates that in a library opened using dlopen(), in a chunk of memory that contains various static variables that would have to be set to 0 according to spec, are instead set to weird values, causing a deadlock. Everything should be initialized in the correct order and there is no threading yet at that point. I have not managed to identify any sources of randomness (inside the program). Asking gdb to break when something touches these variables doesn't show up anything. Etc. With just one core file and no access to the customer's production environment we decided to just restart the program if it deadlocks...
- vlovich123 5y agoHave you tried rr w/ chaos mode?
- qiqitori 5y agoI suggested rr at one point but I think we already blew our time budget (the customer pays us by the hour). I'll read up on the chaos mode, never heard of it. Thanks!
- rightbyte 5y agoFaulty hardware?