[AGENT++] [BUG] Access to freed memory during startup of snmp++v3.2.24 with agent++v3.5.30

Dominik Vogt Dominik.Vogt at external.thalesgroup.com
Fri Jul 23 12:43:19 CEST 2010


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 ^_^  ^_^




More information about the AGENTPP mailing list