On Mar 8, 2006, at 3:47 PM, James Rinker wrote:
Oops. I just realized I typed something other than what I provided as
evidence! Obviously, when I said "...and it is not being hit prior
to..." that should have read "...and it *IS* being hit..." My
apologies.
The rest of the story is the same:
- apr_terminate is called from the APRInitializer destructor.
- After that, the global smart pointers at the bottom of level.cpp are
destructed which in turn try to call apr_atomic_dec32.
Okay, we have established the mechanism. Calling any APR methods
after calls to apr_terminate is unsafe, though the penalty may vary
depending on the platform.
In this case, either something is wrong with the approach that we
have taken with APRInitialize to attempt to force it to be destructed
after the last ObjectImpl is destructed and the problem isn't biting
us on other platforms or we did things right the compiler isn't
properly ordering the destructors per the standard.
The static Level objects aren't essential but are provided as a
convenience for ported log4j code where use of Level.DEBUG and the
like could be common. There are equivalent static methods getDebug()
etc that are not as likely to be affected by compiler issues. If you
aren't using Level::DEBUG and the like, you could suppress them and
see if the problem goes away or if there are other lurking
problems. Since any Level.DEBUG code ported from log4j would need
to be changed to Level::DEBUG, it might not be too bad just to force
people to switch to Level::getDebug(). It would however affect
people who had used log4cxx 0.9.7.