Hello,
First of all, I apologize for this rather lengthy email.
I am new to log4cxx and have recently encountered a memory leak issue with log4cxx-0.9.8.tar.gz.
I downloaded it from http://littletux.homelinux.org/log4cxx
and started playing with the syslog feature
by modifying the console example code provided in the package.
Basically the configure function is modified to use SyslogAppender and
PatternLayout and the main function is modified to include a while loop with a
sleep statement between logging occurrences. The entire modified code is
presented below.
Running the program on Windows XP, I am experiencing a
memory leak of approximately 120 bytes on each logging occurrence.
I wonder if anybody has experienced something similar to
this? After some investigation, I found out that the leak was caused by
the call to apr_sockaddr_info_get in the DatagramSocket::send(DatagramPacketPtr&
p) method (datagramsocket.cpp). At this point I wonder if I am missing
something. Any comment/help would be much appreciated.
Regards,
Min
// datagramsocket.cpp
/** Sends a datagram packet.*/
void DatagramSocket::send(DatagramPacketPtr& p)
{
// create the adress to which to send the
datagram packet
LOG4CXX_ENCODE_CHAR(hostAddr,
p->getAddress().getHostAddress());
apr_sockaddr_t *addr;
apr_status_t status =
apr_sockaddr_info_get(&addr, hostAddr.c_str(), APR_INET, p->getPort(),
0, (apr_pool_t*) memoryPool.getAPRPool());
if (status != APR_SUCCESS) {
throw SocketException(status);
}
// send the datagram packet
apr_size_t len = p->getLength();
status = apr_socket_sendto((apr_socket_t*)
socket, addr, 0,
(char *)p->getData(), &len);
if (status != APR_SUCCESS) {
throw IOException(status);
}
}
// console.cpp - modified
#include <time.h>
#include <sys/timeb.h>
#include <stdlib.h>
#include <log4cxx/logger.h>
#include
<log4cxx/consoleappender.h>
#include
<log4cxx/fileappender.h>
#include
<log4cxx/net/syslogappender.h>
#include
<log4cxx/patternlayout.h>
#include <log4cxx/logmanager.h>
#include <log4cxx/logstring.h>
#include <iostream>
#include <windows.h>
using namespace log4cxx;
using namespace log4cxx::helpers;
static void configure(bool err) {
// try syslog
log4cxx::PatternLayoutPtr
patternLayout(new log4cxx::PatternLayout());
patternLayout->setConversionPattern(L"%r [%t] %d{ISO8601} %-5p [%c]
---> %m%n");
log4cxx::net::SyslogAppenderPtr
appender(new log4cxx::net::SyslogAppender(patternLayout, (logchar
*)(L"10.10.10.166"), 8));
log4cxx::helpers::Pool pool;
appender->activateOptions(pool);
log4cxx::Logger::getRootLogger()->addAppender(appender);
LogManager::getLoggerRepository()->setConfigured(true);
}
int main(int argc, char** argv)
{
if (argc <= 1) {
puts("Console test program\nUsage: console [-err] [ puts | putws | cout |
wcout | configure | log | wide | byte ]*\n");
}
bool configured = false;
bool err = false;
for (int i = 1; i < argc; i++) {
if
(strcmp("-err", argv[i]) == 0) {
err = true;
} else if
(strcmp("puts", argv[i]) == 0) {
fputs("Hello, fputs\n", err ? stderr : stdout);
} else if
(strcmp("putws", argv[i]) == 0) {
fputws(L"Hello, fputws\n", err ? stderr : stdout);
} else if
(strcmp("cout", argv[i]) == 0) {
if (err) {
std::cerr << "Hello, cout" << std::endl;
} else {
std::cout << "Hello, cout" << std::endl;
}
} else if
(strcmp("wcout", argv[i]) == 0) {
if (err) {
std::wcerr << L"Hello, wcout" << std::endl;
} else {
std::wcout << L"Hello, wcout" << std::endl;
}
} else if
(strcmp("configure", argv[i]) == 0) {
configure(err);
configured = true;
} else if
(strcmp("log", argv[i]) == 0) {
if (!configured) {
configure(err);
configured = true;
}
while (true)
{
log4cxx::Logger::getRootLogger()->info("Hello, log4cxx");
::Sleep(200);
}
} else if
(strcmp("wide", argv[i]) == 0) {
fwide(err ? stderr : stdout, 1);
} else if
(strcmp("byte", argv[i]) == 0) {
fwide(err ? stderr : stdout, -1);
} else {
fputs("Unrecognized option: ", stderr);
fputs(argv[i], stderr);
fputs("\n", stderr);
fflush(stderr);
}
}
return 0;
}