Boost logo

Boost Users :

From: Joaquín Mª López Muñoz (joaquin_at_[hidden])
Date: 2008-01-30 12:38:34


Jens Seidel ha escrito:

> On Wed, Jan 30, 2008 at 01:41:15PM +0000, Martin Fisher wrote:
> > Using the boost_1_35_0 svn library download and Visual C++ 2008 Express
> > edition.
> > Originally compiled as a CLR program. Recompiling using native Win32
> > still gives a crash during program termination - in
> > atomic_count_win32.hpp in operator-- (BOOST_INTERLOCKED_DECREMENT)
> > Unhandled exception at 0x010752b9 in fly2.exe: 0xC0000005: Access
> > violation writing location 0x00779040.
>
> There is indeed a bug somewhere. I could reproduce it on Linux which
> doesn't suffer from CLR/libc/... mess. I just compiled it (code from
> trunk) and it crashes. valgrind reports:

[...]

Jens, Martin,

I could also reproduce it here, and found the reason for the crash. Please
follow me:

The static initialization of flyweight<string>'s internal factory (explained in detail at
http://tinyurl.com/2rwwug ) is done automatically before the first use of
flyweight<string> in the program, or before main() at the very latest. But now
let's take a look again at Martin's program:

  vector<boost::flyweight<string> > vec;

  ...

  int main(int argc, char* argv[])
  {
    ...
  }

The static initialization of vec invokes vector<boost::flyweight<string> > ctor, but
this ctor *does not use boost::flyweight<string>*: no flyweight objects are created
during the default initialization of the vector. So, boost::flyweight<string>'s factory
is not guaranteed to be initialized before vec, only before main()! Consequently,
the following is a valid sequence of static initializations and destructions (which
go in reverse order as the corresponding initializations):

  // initialziation of vec
  vector<boost::flyweight<string> > vec;

  // (automatic) initialization of boost::flyweight<string>'s factory

  ...

  int main(int argc, char* argv[])
  {
    ...
  }

  // automatic destruction of boost::flyweight<string>'s factory
  // automatic destruction of vec

And this is the problem: when the factory is destroyed, there are still
flyweight objects around (those in vec), when there should be none,
and on vec's destruction time the flyweight objects point to deallocated
memory, hence the crash.

This is solved by forcing boost::flyweight<string> static initialization
before that of vec:

  boost::flyweights::flyweight<string>::initializer init;
  vector<boost::flyweights::flyweight<string> > vec;

So that static initialization order is correct. Could you please try the fix?

This is a fundamental issue for which I see no easy *automatic* fix upon first
reflection, other than documenting very clearly the situations in which it
can arise. Comments and suggestions welcome.

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net