[ 
https://issues.apache.org/jira/browse/LOGCXX-322?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13934889#comment-13934889
 ] 

Thorsten Schöning commented on LOGCXX-322:
------------------------------------------

Thanks for the patch, I think we already fixed most of those differently by 
simply removing static because function statics are not thread safe at all, 
even for construction. Look at LOGCXX-394 and LOGCXX-430. The only thing we 
didn't change was uncommenting apr_terminate in 
APRInitializer::~APRInitializer(). We need to still have a look at that and 
make sure it's called at the very last possible I think.

> Crashes on exit from multithreaded program using log4cxx
> --------------------------------------------------------
>
>                 Key: LOGCXX-322
>                 URL: https://issues.apache.org/jira/browse/LOGCXX-322
>             Project: Log4cxx
>          Issue Type: Bug
>    Affects Versions: 0.10.0
>         Environment: Linux platform server product, compiled with g++ 4.3.x, 
> running on multi-core IA32 and IA64 hardware
>            Reporter: Ben Hockley
>            Assignee: Curt Arnold
>         Attachments: 130-bugfix-LOGCXX-322.dpatch
>
>
> On exit(0); (attempt at graceful process exit)  we commonly see segmentation 
> faults in:
> * log4cxx::helpers::ObjectPtrBase()
> * log4cxx::LogManager::getLoggerLS()
> The cause
> =======
> We eventually traced this issue to the pervasive pattern of usage of 
> singletons in the log4cxx code.
> The log4cxx library uses the "Meyers" singleton pattern, first popularised in 
> Scott Meyers "Effective C++" (Item 47 in the 2nd edition of that book):
> Thing & getThingSingleton()
> {
>    static Thing t;
>    return t;
> }
> For many years, the above pattern was considered "best practice" for using 
> Singletons in C++ - and was generally safe for most popular compiler 
> implementations and most applications.
> Unfortunately, this recommendation is not actually guaranteed to be 
> thread-safe for construction or destruction - something which is alluded to 
> on Scott Meyers' own "Errata List for Effective C++, Second Edition"
> as described here: http://www.aristeia.com/BookErrata/ec++2e-errata.html
> The nub of the problem is that when a process calls "exit(0);" or similar, 
> one thread will start running, in order, any user-registered "atexit" 
> functions.
> Along with these, the compiler will execute the (conceptually similar) 
> compiler-registered functions which invoke the destructors of any static file 
> or function scope objects (also in order - the reverse order to static object 
> construction).
> Unfortunately, other threads may still be in the process of running -and 
> logging, perhaps using the static objects - during or after the execution of 
> their destructors - thus opening the door to a bunch of potential SEGFAULTs.
> Solutions
> ======
> The solution is to introduce an (optional) new  singleton lifetime management 
> policy.  Specifically, we need to make sure that any Singletons required for 
> log4cxx logging  to operate correctly (including, but not limited to, 
> APRInitializer) are always available when required by any thread - including 
> during process shutdown.
> Andrei Alexandrescu goes into a lot of detail about this C++ design problem 
> in chapter 6 of "Modern C++ design" and proposes two elegant solutions -  a 
> "Phoenix Singleton" or  SingletonHolder class.
> For complete thread-safety, we should also consider the 
> startup/initialization race for each singleton  (for that we'd need a 
> multiple-locked singleton initialization pattern everywhere log4cxx creates a 
> singleton).
> We will need to address the singletons in:
> * aprinitializer.cpp
> * level.cpp
> * logmanager.cpp
> and perhaps elsewhere too.
> An attempt at patching the above files to simply "leak" the crucial singleton 
> objects  seemed to prevent the crashes (but could, of course, cause 
> unacceptable behaviour in certain embedded environments - or in environments 
> using memory leak checkers like Boundshecker, Purify, Valgrind etc.) 
> Curt Arnold suggested (on the mailing list) "Probably the best approach is to 
> try to isolate the singleton pattern into a preprocessor macro and then allow 
> the user to select what singleton pattern they'd like to use." - something 
> which sounds like a very wise idea.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to