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.

Reply via email to