Boost logo

Boost :

Subject: Re: [boost] [serialization] Massive failures in develop?
From: Robert Ramey (ramey_at_[hidden])
Date: 2015-10-18 11:37:11


On 10/18/15 12:47 AM, John Maddock wrote:
>

> I think this is the correct way to do things (and is what my patch does,
> but I'm fine if you revert to the old way).

I've included the original stream_buffer_saver. I had originally taken
it out to simplify things to track down the original issue. So things
should be fine now. I've tested it on my machine which includes gcc and
clang and also tested on C++03 and C++11. I've also got my bjam
settings so that I think any visibility failures should be detectible on
my system. I've uploaded these changes to develop and hopefully thing
should start looking good. We'll see.
>
> If you do any other thing then you introduce facet-lifetime issues as
> the archive is destroyed before the iostream leaving the iostream's
> locale with a dangling pointer (even making the facet lifetime global in
> the serialization lib doesn't work, because if someone writes an archive
> to cout, then the serialization lib is unloaded before the std lib and
> cout is left with a dangling pointer again).

I get this - that is the point of the stream_buffer_saver. When it's
destroyed, it puts the streambuffer back into it's orginal state.

Things were made more complicated by the standard codecvt idiom of
allocating with new and letting the stream buffer manage the lifetime.
Also it's very hard to figure out the design and motivation of the
standard library's usage of facets etc. Also, it seems I'm not the only
one with this problem. I don't have confidence that all the standard
library implementations have this exactly right.

> Let me know if you have a test case you want me to try and debug,

The original test case which set me on this path is contained in the
test_z test which is what I use to hold the current test case I'm
working on. FWIW - my procedure is:

a) select a trac item which looks the simplest from the list and has a
reasonable test case.
b) copy the test case into the test_z source code.
c) make sure it fails on my machine
d) often I discover that the user has made some mistake, In this case
I'll inform the user on the trac item - which keeps a whole thread of
dialog between myself and complainer. Usually I'm right then I can just
be done. Sometimes I might tweak the documentation in the hope of not
getting another similar bogus complaint
e) If it's legitimate, I'll debug it and make a change
f) about half the time, this has an unintended and maybe obscure side
effect which turns the process into a much bigger operation than
anticipated.
g) I check in the changes into develop and usually find that I've broken
something in some environment I don't have. So the loop continues.
h) By this time, I want to give up and just role things back and live
with the bug. But I can't do that because I've already invested too much
to just do that. I know that this is sort of irrational as it's a "sunk
cost". But I always convince myself that "I'm almost there - just one
more iteration".
i) finally it's done and everything works everywhere.
j) so I check into master.
k) then the cycle continues a little longer.
l) things stop happening and then I guess it's done.

I only relate the above for those interested in what it means to be a
boost library maintainer. It means you've got a borderline personality
disorder which you attempt to address by indulging it. Guess it works
for me.

So I do appreciate your help and participation in cases such as this.

Robert Ramey


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk