On Aug 21, 2007, at 12:15 PM, Brian wrote:

I have an application that uses multiple loggers (15), each owned by a different thread, that is writing to a different file. Executing the application starts the logger but soon the application cores. I wrote a test application to rule out my code and I still see the same problem. (I am also seeing logs with bad output) This works fine on Windows but in Linux it cores. This is being run on a multiprocessor box with no hyper threading.

Has anyone else seen this problem? I also tried the test program with org.apache.log4j.FileAppender.

Thanks
  Brian

Sorry about the long delay. I finally built your test on Linux and got an immediate segfault in the first initialization of LoggerPtr. The reason this is occurring on Linux and not Windows is the implementation of apr_atomic_xchg32 on Windows delegates to a Windows API method which will work if called before APR initialization and the Linux implementation requires that APR be initialized. The implementation of a LoggerPtr isn't sufficient to trigger APR initialization.

If instead of

log4cxx::LoggerPtr logger;
    try
    {
        // Get Logger
        logger = log4cxx::Logger::getLogger(loggerName);
    }
    catch(...)
    {
std::cout << "Failed to get logger = " << loggerName << std::endl;
        return 0;
    }

I did:

log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger(loggerName));


I no longer got an immediate segfault as the call to getLogger() will trigger the call to load APR before the LoggerPtr constructor calls apr_atomic_xchg32. With that change, I still got an segfault on application shutdown. I didn't trace that issue down, but it appears likely due to APR being de-initialized when the thread that originally initialized it went out of scope, leaving the other threads using a non-functioning APR. That problem could be addressed by initializing APR in the main thread (likely by calling Logger::getLogger in either a constructor of a static object).

Basically, log4cxx is safe to use on multi-threads, but it isn't safe to initialize or configure on an arbitrary thread. Apps near to do something to trigger initialization and configuration either on module load time (happens automatically with a static LoggerPtr instance) or on the main thread.


Reply via email to