Details
Description
I am using the latest SVN head of this project. First and foremost, it is important to note that I am NOT using ant to build this project. I am using the normal configure and make process, i.e.:
./autogen.sh
./configure
make
sudo make install
When I compile a very simple test program for the logger and run it using Valgrind (http://valgrind.org/), it shows that memory is not being deallocated at the end of the program. Here is the simple program I am compiling:
===test.cc===
#include <iostream>
#include <log4cxx/logger.h>
#include <log4cxx/patternlayout.h>
#include <log4cxx/consoleappender.h>
using namespace log4cxx;
using namespace log4cxx::helpers;
int main()
{
/////////////////////////////////////////////////
// log4cxx configuration
/////////////////////////////////////////////////
// Create pattern layout
PatternLayoutPtr patternLayout(new PatternLayout());
patternLayout->setConversionPattern(LOG4CXX_STR("%d
[%-5p] (%l:%c
{5}): %m %n"));
// Create console appender
ConsoleAppenderPtr consoleAppender(new ConsoleAppender(patternLayout));
// Get rootLogger add appenders
LoggerPtr rootLogger = Logger::getRootLogger();
rootLogger->addAppender(consoleAppender);
/////////////////////////////////////////////////
// end log4cxx configuration
/////////////////////////////////////////////////
// Doing some interesting stuff that needs logging
LOG4CXX_DEBUG(rootLogger, "debug message");
LOG4CXX_INFO(rootLogger, "info message");
LOG4CXX_WARN(rootLogger, "warn message");
LOG4CXX_ERROR(rootLogger, "error message");
LOG4CXX_FATAL(rootLogger, "fatal message");
}
===/test.cc===
I compile with
g++ -g -llog4cxx test.cc
and run through valgrind with
valgrind --tool=memcheck --leak-check=full --show-reachable=yes a.out
which produces:
==25981== Memcheck, a memory error detector.
==25981== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==25981== Using LibVEX rev 1732, a library for dynamic binary translation.
==25981== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==25981== Using valgrind-3.2.3, a dynamic binary instrumentation framework.
==25981== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==25981== For more details, rerun with: -v
==25981==
-25981- DWARF2 CFI reader: unhandled CFI instruction 0:50
-25981- DWARF2 CFI reader: unhandled CFI instruction 0:50
-25981- DWARF2 CFI reader: unhandled CFI instruction 0:50
-25981- DWARF2 CFI reader: unhandled CFI instruction 0:50
2007-12-07 10:16:29 [DEBUG] (test2.cc(32):root): debug message
2007-12-07 10:16:29 [INFO ] (test2.cc(33):root): info message
2007-12-07 10:16:29 [WARN ] (test2.cc(34):root): warn message
2007-12-07 10:16:29 [ERROR] (test2.cc(35):root): error message
2007-12-07 10:16:29 [FATAL] (test2.cc(36):root): fatal message
==25981==
==25981== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 49 from 1)
==25981== malloc/free: in use at exit: 65,640 bytes in 9 blocks.
==25981== malloc/free: 2,523 allocs, 2,514 frees, 131,220 bytes allocated.
==25981== For counts of detected errors, rerun with: -v
==25981== searching for pointers to 9 not-freed blocks.
==25981== checked 596,280 bytes.
==25981==
==25981== 104 bytes in 1 blocks are still reachable in loss record 1 of 2
==25981== at 0x401C6FE: malloc (vg_replace_malloc.c:149)
==25981== by 0x45854BE: apr_allocator_create (in /usr/lib/libapr-1.so.0.2.7)
==25981== by 0x4585D35: apr_pool_initialize (in /usr/lib/libapr-1.so.0.2.7)
==25981== by 0x458767E: apr_initialize (in /usr/lib/libapr-1.so.0.2.7)
==25981== by 0x40AC818: log4cxx::helpers::APRInitializer::APRInitializer() (aprinitializer.cpp:31)
==25981== by 0x40AC928: log4cxx::helpers::APRInitializer::getInstance() (aprinitializer.cpp:54)
==25981== by 0x40AC975: log4cxx::helpers::APRInitializer::initialize() (aprinitializer.cpp:60)
==25981== by 0x411668F: log4cxx::helpers::ObjectImpl::ObjectImpl() (objectimpl.cpp:27)
==25981== by 0x412036B: log4cxx::PatternLayout::PatternLayout() (patternlayout.cpp:57)
==25981== by 0x80491F2: main (test2.cc:17)
==25981==
==25981==
==25981== 65,536 bytes in 8 blocks are still reachable in loss record 2 of 2
==25981== at 0x401C6FE: malloc (vg_replace_malloc.c:149)
==25981== by 0x4585A9D: apr_pool_create_ex (in /usr/lib/libapr-1.so.0.2.7)
==25981== by 0x4585D74: apr_pool_initialize (in /usr/lib/libapr-1.so.0.2.7)
==25981== by 0x458767E: apr_initialize (in /usr/lib/libapr-1.so.0.2.7)
==25981== by 0x40AC818: log4cxx::helpers::APRInitializer::APRInitializer() (aprinitializer.cpp:31)
==25981== by 0x40AC928: log4cxx::helpers::APRInitializer::getInstance() (aprinitializer.cpp:54)
==25981== by 0x40AC975: log4cxx::helpers::APRInitializer::initialize() (aprinitializer.cpp:60)
==25981== by 0x411668F: log4cxx::helpers::ObjectImpl::ObjectImpl() (objectimpl.cpp:27)
==25981== by 0x412036B: log4cxx::PatternLayout::PatternLayout() (patternlayout.cpp:57)
==25981== by 0x80491F2: main (test2.cc:17)
==25981==
==25981== LEAK SUMMARY:
==25981== definitely lost: 0 bytes in 0 blocks.
==25981== possibly lost: 0 bytes in 0 blocks.
==25981== still reachable: 65,640 bytes in 9 blocks.
==25981== suppressed: 0 bytes in 0 blocks.
I have traced this down to a possible problem in the APRInitializer class. The offending code appears to be in arpinitializer.cpp in the destructor of APRInitializer:
APRInitializer::~APRInitializer()
{ // // If we are using a static APR then // we need to clean up after ourselves // otherwise the main executable should terminate APR // #if defined(APR_DECLARE_STATIC) && !defined(LOG4CXX_DECLARE_STATIC) apr_terminate(); #endif isDestructed = true; }The apr_terminate() function does not get compiled into my log4cxx library because APR_DECLARE_STATIC is not defined. I do not know what in the build process should be defining this, but if i forcefully define the compiler flag, then everything works fine. For example, if I use this sequence for my installation process:
export CPPFLAGS=-DAPR_DECLARE_STATIC=1
./autogen.sh
./configure
make
sudo make install
then everything works fine, and valgrind reports no memory leaks.
I have used other incarnations that have stemmed from this logger's code-base (log4cplus, log4cpp) and all seem to have some form of memory leak or other, but I have settled on using log4cxx because it seems the most mature, and the only one that is under active development. There is a distinct possibility that there is no bug or problem with the code at all, and that I am just not using it correctly. I that is the case, then please advise!
This sort of issue would probably have been best raised in a forum thread before becoming a bug report, but I couldn't seem to find a forum for the log4cxx project. If there is one then, then could someone point me to it.
Thanks for your hard work and time,
Lee