On 17/10/2018 04:15, Alexander Grund wrote:
As you mentioned it: #105 adds more CI #110 includes #105 and tests that singletons are eventually destructed and `is_destroyed` returns true in both use cases of the singleton #111 Is the condensed version of my MWE that shows the crash. Essence: Use 2 shared libraries linked against static boost and each uses a part of Boost.Serialization. The crash comes from a destruction order problem, that is currently unsolved and could be avoided if `is_destroyed` would return true, but it doesn't
Granted that I have not looked at the code or the PR in any detail (and thus this might be entirely off base): Conceptually "is_destroyed" is usually a bad idea. By definition, after the destructor has run the memory is free to get stomped on by other objects and thus you can't rely on is_destroyed to return any particular value. Trying to rely on it is UB. Applying this to singletons at global scope is both a blessing and a curse -- it reduces the likelihood that something else would actually stomp over the memory in practice, but also introduces a static destruction order indeterminacy issue. Usually the motivation to introduce this sort of thing is a side effect of having dangling pointers to deleted objects. In which case usually the best solution is to recognise that you actually have a shared ownership issue (where the object's actual lifetime is not what you thought it was) and start using shared_ptr/weak_ptr and/or having an object keep track of which singleton it is registered with rather than assuming that it will find the same ambient singleton later. Having said *that*, as previously discussed on the list, using a static library from multiple shared libraries in itself introduces an aliasing problem, where sometimes singletons aren't actually singletons -- and woe betide you if you try to pass an object that references one singleton across the library divide into the domain of the other singleton, because then you can have issues such as registering with one singleton and then trying to deregister from the other (which all by itself can be a source of dangling pointers). (FWIW, introducing dynamic libraries also increases the risk of dangling pointers, if a library can be unloaded while references to it survive outside.) As far as I am aware (when you are using static-from-dynamic), you will get these duplicated singletons at all times on Windows, and on Linux it will happen whenever you are compiling with -fvisibility=hidden (which appears to be true in this case given the build output) and if the singleton definitions don't use BOOST_SYMBOL_VISIBLE. I leave it to the rest of you to figure out whether this points at an underlying issue in Boost.Serialization or whether it's a usage error. Or both.