[AGENT++] [BUG] Access to freed memory during startup of snmp++v3.2.24 with agent++v3.5.30
Jochen Katz
katz at agentpp.com
Sun Jul 25 21:50:25 CEST 2010
Hi
to make it short: you're right. When calling log() from multiple threads
while instance is not yet set, anything can happen.
Until the next release the workaround is: Call init yourself or log
something before doing any other agent++/snmp++ call and don't call init
while any other thread could do some logging.
Regards,
Jochen
Am 23.07.2010 12:43, schrieb Dominik Vogt:
> There is a bug in the startup code of the logging facility in snmp
> ++v3.2.24. The problem depends on timing and sometimes causes access to
> already freed memory and sometimes even a crash.
>
> In the class DefaultLog in log.h there are two inline functions:
>
> static void init(AgentLog* logger)
> { if (instance) delete instance; instance = logger; }
>
> static AgentLog* log()
> { if (!instance) init(new AgentLogImpl()); return instance; }
>
> Obviously there is no protection agains parallel execution by multiple
> threads. The first thread may have already instantiated the class in
> the init() function but not set the instance member when the second
> thread comes in, notices there is not yet an instance, calls init()
> again and deletes the now set instance member. You know the story.
>
> This actually does happen in threads.cpp fron agent++v3.5.30. I'm not
> perfectly sure about the circumstances, but I believe it's like this:
>
> 1. The TaskManager is created by calling its constructor:
>
> TaskManager::TaskManager(ThreadPool *tp, int stackSize):thread(*this)
> {
> ...
> thread.start();
> LOG_BEGIN(DEBUG_LOG | 1);
> LOG("TaskManager: thread started");
> LOG_END;
> }
>
> 2. The constructor starts a thread and then emits a log message.
>
> 3. The current thread enters DefaultLog::log() and DefaultLog::init() as
> described above.
>
> 4. The new thread enters the function thread_starter():
>
> void* thread_starter(void* t)
> {
> Thread *thread = (Thread*)t;
> Thread::threadList.add(thread);
>
> #ifndef NO_FAST_MUTEXES
> LOG_BEGIN(DEBUG_LOG | 1);
> LOG("Thread: started (tid)");
> LOG((int)(thread->tid));
> LOG_END;
> #endif
>
> 5. There it also tries to emit a log message while the first thread is
> still initializing the DefaultLog.
>
> (This is what I see in the stack traces from my debugging sessions.)
>
> --
>
> It's probably possible to work around the problem by simply calling
> DefaultLog::log() the the main() function of the application.
>
> Ciao
>
> Dominik ^_^ ^_^
>
> _______________________________________________
> AGENTPP mailing list
> AGENTPP at agentpp.org
> http://lists.agentpp.org/mailman/listinfo/agentpp
>
More information about the AGENTPP
mailing list