|
Boost : |
Subject: Re: [boost] "peer reviewed" - Rights and responsibilities of maintainers
From: Gavin Lambert (boost_at_[hidden])
Date: 2018-10-16 23:29:39
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.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk