logging-log4cxx-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Curt Arnold <carn...@houston.rr.com>
Subject Re: SIGSEGV on log4cxx initialisation
Date Fri, 27 Aug 2004 09:06:32 GMT

On Aug 27, 2004, at 3:27 AM, Tom Quarendon wrote:

> Right. So to make log4cxx work properly across multiple DLLs with all 
> my C++
> classes having static LoggerPtr objects I need to indulge in some 
> serious
> use of the GCC "init_priority" attribute to control initialisation 
> order.
> Surely there is a recognised way of going this -- doesn't everyone have
> static LoggerPtr objects in their classes? All my classes are like :
>
> fred.hpp
> ========
> class Fred {
> 	static log4cxx::LoggerPtr logger;
> ...
>
> };
>
> fred.cpp
> ========
>
> log4cxx::LoggerPtr Fred::logger = log4cxx::Logger::getLogger("fred");
>
> From what you are saying, in order for this to work properly I need to 
> make
> sure that the static initialisation of logger in fred.cpp is done 
> after any
> static initialisation in the log4cxx DLL. Maybe the way to do it is
>
...

> Is there a recommended way of doing this kind of stuff?
>
>

Looks like we have the dreaded non-local static variable somewhere in 
log4cxx.  The scenario is Item 47 in Effective C++.  Any access to 
static variables within log4cxx needs to be down using local static 
variables so that initialization is forced to occur on first use.  I 
haven't done a search and the following is a  simplistic example.  
Unsafe:

LogManager gLogManager;

public LoggerPtr Logger::GetLogger(const char* name) {
    //  gLogManager might not be initialized
     return gLogManager.GetLogger(name);
}

Safe:

public LogManager& GetGlobalManager() {
    //  initialization occurs first time through
    static LogManager gLogManager;
    return gLogManager;
}

public LoggerPtr Logger::GetLogger(const char* name) {

     return GetGlobalManager.GetLogger(name);
}


Until it is fixed in log4cxx, you could use the same trick in your code 
to force the call to getLogger to occur after all static 
initialization.

class MyClass {

private static LoggerPtr GetLogger() {
     static LoggerPtr myLogger = log4cxx::Logger::GetLogger("foo");
    return myLogger;
}


public MyClass() {
    LOG4CXX_DEBUG(GetLogger(), "Constructor");
}
};



Mime
View raw message