apache / logging-log4cxx

Apache Log4cxx is a C++ port of Apache Log4j
http://logging.apache.org/log4cxx
Apache License 2.0
278 stars 123 forks source link

Creating a static NDC causes a segfault on exit in 1.3.0 #425

Closed wrohv closed 3 weeks ago

wrohv commented 3 weeks ago

After updating to log4cxx 1.3.0, I find that statically allocated NDC objects cause a segmentation fault at application exit. This wasn't the case in prior versions. I'm on MacOS on arm.

Just adding these lines to any code can cause the issue for me:

#include <log4cxx/ndc.h>
static log4cxx::NDC ndc("MyNDC");

The lldb stack trace shows the issue arising from the destructor of the static object:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x28)
  * frame #0: 0x00000001001ff678 liblog4cxx.15.dylib`log4cxx::NDC::pop() + 36
    frame #1: 0x00000001001ff62c liblog4cxx.15.dylib`log4cxx::NDC::~NDC() + 28
    frame #2: 0x000000018b6b2998 libsystem_c.dylib`__cxa_finalize_ranges + 476
    frame #3: 0x000000018b6b275c libsystem_c.dylib`exit + 44
    frame #4: 0x000000018b81a94c libdyld.dylib`dyld4::LibSystemHelpers::exit(int) const + 20
    frame #5: 0x000000018b4742c8 dyld`start + 2924
swebb2066 commented 3 weeks ago

This wasn't the case in prior versions.

In release 1.3 ThreadSpecificData switched from using APR apr_threadkey_private_get to using C++ thread_local where the compiler supports thread_local.

Could you advise us which compiler version you are using?

rm5248 commented 3 weeks ago

Are you exiting gracefully(e.g. stopping all threads) when you exit? There are some issues with exiting uncleanly(e.g. by calling exit()) due to static objects being destroyed while threads may still be running.

wrohv commented 3 weeks ago

I am on MacOS 15.1.

> clang --version
Apple clang version 16.0.0 (clang-1600.0.26.4)

Here's a full reproducing example, where I started from "A Simple Example" at https://logging.apache.org/log4cxx/1.3.0/quick-start.html

#include <log4cxx/logger.h>
#include <log4cxx/basicconfigurator.h>

#include <log4cxx/ndc.h>
static log4cxx::NDC ndc("MyNDC");

static auto logger = log4cxx::Logger::getLogger("MyApp");

int main(int argc, char **argv) {
    // Log to standard output.
    log4cxx::BasicConfigurator::configure();
    LOG4CXX_INFO(logger, "Exiting application.");
    return EXIT_SUCCESS;
}
wrohv commented 3 weeks ago

I tried the linked pull request branch and it appears to solve the problem for me. Thanks!