[ https://issues.apache.org/jira/browse/LOGCXX-430?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15175254#comment-15175254 ]
Thorsten Schöning commented on LOGCXX-430: ------------------------------------------ Another issue was reported on the list which looks similar to the one described here. It's a crash at exiting the process and seem to have its root cause in LogManager::getRepositorySelector(): {CODE} log4cxx_adtyco_tpl.dll!`log4cxx::LogManager::getRepositorySelector'::`2'::`dynamic atexit destructor for 'selector''() {CODE} One workaround for the problem was to apply the following changes: {CODE} Hierarchy::~Hierarchy() { // LOGCXX-430 #ifndef APR_HAS_THREADS delete loggers; delete provisionNodes; #endif } {CODE} It's basically the same workaround like applied to APRInitializer in LOGCXX-322 and as it seems currently the only way to fix the problem for the user, I'l apply those changes with a hint to this comment. There's some destructing going on at least to the loggers when it's already too late: {CODE} >msvcr120.dll!abort() Line 88C log4cxx_adtyco_tpl.dll!log4cxx::helpers::ObjectPtrT<log4cxx::Logger>::~ObjectPtrT<log4cxx::Logger>() Line 102 log4cxx_adtyco_tpl.dll!log4cxx::helpers::ObjectPtrT<log4cxx::Logger>::`vector deleting destructor'() log4cxx_adtyco_tpl.dll!std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::pattern::PatternConverter> {CODE} The complete discussion can be found at: http://mail-archives.apache.org/mod_mbox/logging-log4cxx-dev/201602.mbox/browser The complete stacktrace: {CODE} >msvcr120.dll!abort() Line 88C log4cxx_adtyco_tpl.dll!log4cxx::helpers::ObjectPtrT<log4cxx::Logger>::~ObjectPtrT<log4cxx::Logger>() Line 102 log4cxx_adtyco_tpl.dll!log4cxx::helpers::ObjectPtrT<log4cxx::Logger>::`vector deleting destructor'() log4cxx_adtyco_tpl.dll!std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::pattern::PatternConverter> >::destroy<log4cxx::helpers::ObjectPtrT<log4cxx::pattern::PatternConverter> >(_Ptr=0x08f4df48) Line 608 log4cxx_adtyco_tpl.dll!std::allocator_traits<std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::spi::HierarchyEventListener> > >::destroy<log4cxx::helpers::ObjectPtrT<log4cxx::spi::HierarchyEventListener> >(_Al={...}, _Ptr=0x08f4df48) Line 731 log4cxx_adtyco_tpl.dll!std::_Wrap_alloc<std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::helpers::ObjectOutputStream> > >::destroy<log4cxx::helpers::ObjectPtrT<log4cxx::helpers::ObjectOutputStream> >(_Ptr=0x08f4df48) Line 879 log4cxx_adtyco_tpl.dll!std::_Destroy_range<std::_Wrap_alloc<std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::helpers::ObjectOutputStream> > > >(_First=0x08f4df48, _Last=0x08f4df50, _Al={...}, __formal={...}) Line 82 log4cxx_adtyco_tpl.dll!std::_Destroy_range<std::_Wrap_alloc<std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::helpers::InetAddress> > > >(_First=0x08f4df48, _Last=0x08f4df50, _Al={...}) Line 96 log4cxx_adtyco_tpl.dll!std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::helpers::Socket>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::helpers::Socket> > >::_Destroy(_First=0x08f4df48, _Last=0x08f4df50) Line 1567 log4cxx_adtyco_tpl.dll!std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::helpers::Socket>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::helpers::Socket> > >::_Tidy() Line 1628 log4cxx_adtyco_tpl.dll!std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::helpers::Socket>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::helpers::Socket> > >::~vector<log4cxx::helpers::ObjectPtrT<log4cxx::helpers::Socket>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::helpers::Socket> > >() Line 946 log4cxx_adtyco_tpl.dll!std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > >::~pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > >() log4cxx_adtyco_tpl.dll!std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > >::`scalar deleting destructor'() log4cxx_adtyco_tpl.dll!std::allocator<std::_Tree_node<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > >,void *> >::destroy<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > > >(_Ptr=0x1921d550) Line 608 log4cxx_adtyco_tpl.dll!std::allocator_traits<std::allocator<std::_Tree_node<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > >,void *> > >::destroy<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > > >(_Al={...}, _Ptr=0x1921d550) Line 731 log4cxx_adtyco_tpl.dll!std::_Wrap_alloc<std::allocator<std::_Tree_node<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > >,void *> > >::destroy<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > > >(_Ptr=0x1921d550) Line 879 log4cxx_adtyco_tpl.dll!std::_Tree<std::_Tmap_traits<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >,std::less<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > >,std::allocator<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > > >,0> >::_Erase(_Rootnode=0x1921d540) Line 2083 log4cxx_adtyco_tpl.dll!std::_Tree<std::_Tmap_traits<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >,std::less<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > >,std::allocator<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > > >,0> >::_Erase(_Rootnode=0x1921da80) Line 2079 log4cxx_adtyco_tpl.dll!std::_Tree<std::_Tmap_traits<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >,std::less<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > >,std::allocator<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > > >,0> >::clear() Line 1541 log4cxx_adtyco_tpl.dll!std::_Tree<std::_Tmap_traits<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >,std::less<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > >,std::allocator<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > > >,0> >::erase(_First={...}, _Last={...}) Line 1515 log4cxx_adtyco_tpl.dll!std::_Tree<std::_Tmap_traits<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >,std::less<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > >,std::allocator<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > > >,0> >::_Tidy() Line 2231 log4cxx_adtyco_tpl.dll!std::_Tree<std::_Tmap_traits<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >,std::less<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > >,std::allocator<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > > >,0> >::~_Tree<std::_Tmap_traits<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >,std::less<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > >,std::allocator<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > > >,0> >() Line 1193 log4cxx_adtyco_tpl.dll!std::map<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >,std::less<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > >,std::allocator<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > > > >::~map<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >,std::less<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > >,std::allocator<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > > > >() log4cxx_adtyco_tpl.dll!std::map<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > >,std::less<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > >,std::allocator<std::pair<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > const ,std::vector<log4cxx::helpers::ObjectPtrT<log4cxx::Logger>,std::allocator<log4cxx::helpers::ObjectPtrT<log4cxx::Logger> > > > > >::`scalar deleting destructor'() log4cxx_adtyco_tpl.dll!log4cxx::Hierarchy::~Hierarchy() Line 71 log4cxx_adtyco_tpl.dll!log4cxx::Hierarchy::`vbase destructor'() log4cxx_adtyco_tpl.dll!log4cxx::Hierarchy::`vector deleting destructor'() log4cxx_adtyco_tpl.dll!log4cxx::helpers::ObjectImpl::releaseRef() Line 46 log4cxx_adtyco_tpl.dll!log4cxx::Hierarchy::releaseRef() Line 80 log4cxx_adtyco_tpl.dll!log4cxx::helpers::ObjectPtrT<log4cxx::spi::LoggerRepository>::~ObjectPtrT<log4cxx::spi::LoggerRepository>() Line 102 log4cxx_adtyco_tpl.dll!log4cxx::spi::DefaultRepositorySelector::~DefaultRepositorySelector() log4cxx_adtyco_tpl.dll!log4cxx::spi::DefaultRepositorySelector::`vbase destructor'() log4cxx_adtyco_tpl.dll!log4cxx::spi::DefaultRepositorySelector::`vector deleting destructor'() log4cxx_adtyco_tpl.dll!log4cxx::helpers::ObjectImpl::releaseRef() Line 46 log4cxx_adtyco_tpl.dll!log4cxx::spi::DefaultRepositorySelector::releaseRef() Line 36 log4cxx_adtyco_tpl.dll!log4cxx::helpers::ObjectPtrT<log4cxx::spi::RepositorySelector>::~ObjectPtrT<log4cxx::spi::RepositorySelector>() Line 102 log4cxx_adtyco_tpl.dll!`log4cxx::LogManager::getRepositorySelector'::`2'::`dynamic atexit destructor for 'selector''() log4cxx_adtyco_tpl.dll!_CRT_INIT(hDllHandle, dwReason, lpreserved) Line 416C log4cxx_adtyco_tpl.dll!__DllMainCRTStartup(hDllHandle=0x0c4d0000, dwReason=0, lpreserved=0x00000001) Line 522C log4cxx_adtyco_tpl.dll!_DllMainCRTStartup(hDllHandle=0x0c4d0000, dwReason=0, lpreserved=0x00000001) Line 472C ntdll.dll!_LdrxCallInitRoutine@16‑()Unknown ntdll.dll!LdrpCallInitRoutine()Unknown ntdll.dll!LdrShutdownProcess()Unknown ntdll.dll!RtlExitUserProcess()Unknown AcLayers.dll!NS_FaultTolerantHeap::FthExitUserProcess‑()Unknown AcLayers.dll!NS_FaultTolerantHeap::APIHook_RtlExitUserProcess‑()Unknown kernel32.dll!_ExitProcessImplementation@4‑()Unknown mscoreei.dll!RuntimeDesc::ShutdownAllActiveRuntimes‑()Unknown mscoreei.dll!CLRRuntimeHostInternalImpl::ShutdownAllRuntimesThenExit‑()Unknown clr.dll!EEPolicy::ExitProcessViaShim‑()Unknown clr.dll!SafeExitProcess‑()Unknown clr.dll!HandleExitProcessHelper()Unknown clr.dll!EEPolicy::HandleExitProcess‑()Unknown clr.dll!__CorExeMainInternal@0‑()Unknown clr.dll!__CorExeMain@0‑()Unknown mscoreei.dll!__CorExeMain@0‑()Unknown mscoree.dll!__CorExeMain_Exported@0‑()Unknown kernel32.dll!@BaseThreadInitThunk@12‑()Unknown ntdll.dll!__RtlUserThreadStart()Unknown ntdll.dll!__RtlUserThreadStart@8‑()Unknown {CODE} > LogManager::getRootLogger is not thread-safe > -------------------------------------------- > > Key: LOGCXX-430 > URL: https://issues.apache.org/jira/browse/LOGCXX-430 > Project: Log4cxx > Issue Type: Bug > Components: Core > Affects Versions: 0.10.0 > Reporter: Thorsten Schöning > Assignee: Thorsten Schöning > Attachments: LOGCXX-430-with-mutex-1.patch, > LOGCXX-430-with-mutex-2.patch, LOGCXX-430.patch > > > Kaspar Fischer reported following on the user mailing list: > > I am running into a situation where calling getRootLogger() > > concurrently from many requests results in a EXC_BAD_ACCESS: > > liblog4cxx.10.dylib`log4cxx::LogManager::getRootLogger(): > > 0x101f180a0: pushq %rbp > > 0x101f180a1: movq %rsp, %rbp > > 0x101f180a4: pushq %rbx > > 0x101f180a5: pushq %rax > > 0x101f180a6: movq %rdi, %rbx > > 0x101f180a9: callq 0x101f17de0 ; > > log4cxx::LogManager::getLoggerRepository() > > 0x101f180ae: movq 8(%rax), %rsi > > 0x101f180b2: movq (%rsi), %rax > > 0x101f180b5: movq %rbx, %rdi > > 0x101f180b8: callq *120(%rax) <<<<<< THREAD 1: EXC_BAD_ACCESS > > (code=EXC_I386_GPFLT) > > 0x101f180bb: movq %rbx, %rax > > 0x101f180be: addq $8, %rsp > > 0x101f180c2: popq %rbx > > 0x101f180c3: popq %rbp > > 0x101f180c4: ret > > 0x101f180c5: nopw %cs:(%rax,%rax) > > If I replace the logging statement with a statement that writes to > > std::cerr, I do not run into any problems. > > I am using log4cxx 0.10.0 on MacOS 10.9.1. > The call to getRootLogger ultimately results in: > {CODE} > RepositorySelectorPtr& LogManager::getRepositorySelector() { > // > // call to initialize APR and trigger "start" of logging clock > // > APRInitializer::initialize(); > static spi::RepositorySelectorPtr selector; > return selector; > } > {CODE} > It looks like we have the same problem here like in LOGCXX-394, a function > static which is not thread-safe. Therefore we shoudl fix this like we did in > LOGCXX-394 by removing the function static. > Problem is that for this to work we need to change the return type of the > function, which shouldn't be a problem because it's private, but need to > change additional functions as well: getLoggerRepository and > setRepositorySelector both currently rely on the current behavior of > getRepositorySelector. > Additionally what I don't understand is why APRInitializer is called more > than once even if RepositorySelector only got created once because of it's > static. > Looks ike we need to rework the whole part, maybe make it static on a class > level like the guard. -- This message was sent by Atlassian JIRA (v6.3.4#6332)