-
Notifications
You must be signed in to change notification settings - Fork 566
Open
Description
Hi,
I use log4cplus 2.0.2 compiled with --disable-implicit-initialization. To test I worte a test program initializing log4cplus, calling two times LOG4CPLUS_INFO and deinitialize log4cplus. To check for memory leaks I run the program using valgrind. In addition I added some printf to ThreadPool.h and global-init.cxx for a better understanding.
I see that even though the source was compiled with --disable-implicit-initialization, static initialization still occurs. The second issue is the findings of valgrind.
Please find my test program and the valgrind / test program output below.
Regards.
#include <stdio.h>
#include <log4cplus/clogger.h>
#include <log4cplus/initializer.h>
#include <log4cplus/configurator.h>
#include <log4cplus/hierarchy.h>
#include <log4cplus/loggingmacros.h>
#include <string>
using namespace std;
#define LOGGER_NAME "log4cplustest"
log4cplus::Initializer* log4cplusInstance = 0;
log4cplus::Logger rootLogger;
void initLogger(const string& loggerName) {
// get config file
string configFile = loggerName + ".properties";
// read new config
log4cplus::PropertyConfigurator config(configFile,
log4cplus::Logger::getDefaultHierarchy(),
log4cplus::PropertyConfigurator::fAllowEmptyVars);
// apply new config
log4cplus::Logger::getRoot().getHierarchy().resetConfiguration();
config.configure();
rootLogger = log4cplus::Logger::getInstance(loggerName);
LOG4CPLUS_INFO_FMT(LOGGER_NAME, "logging initialized for %s", loggerName.c_str());
}
void openLogFile() {
log4cplusInstance = new log4cplus::Initializer();
rootLogger = log4cplus::Logger::getRoot();
initLogger(LOGGER_NAME);
}
void closeLogFile() {
delete log4cplusInstance;
}
int main(int , char** , char** ) {
openLogFile();
LOG4CPLUS_INFO(LOGGER_NAME, "Started.");
LOG4CPLUS_INFO(LOGGER_NAME, "Done.");
closeLogFile();
return 0;
}
$ /opt/valgrind/bin/valgrind log4cplustest
==1831446== Memcheck, a memory error detector
==1831446== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==1831446== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==1831446== Command: log4cplustest
==1831446==
alloc_dc(): Created DefaultContext 0x64bcb90
ThreadPool::ThreadPool: 0x64c8630, pool_size: 4
ThreadPool::start_worker: workers.push_back() 0
ThreadPool::start_worker: workers.push_back() 1
ThreadPool::start_worker: workers.push_back() 2
ThreadPool::start_worker: workers.push_back() 3
DefaultContext::shutdown_thread_pool(): Calling delete of thread_pool 0x64c8630
ThreadPool::~ThreadPool: 0x64c8630
ThreadPool::start_worker(): stop: t, tasks: 0, worker_number: 3
ThreadPool::start_worker(): stop: t, tasks: 0, worker_number: 0
ThreadPool::start_worker(): stop: t, tasks: 0, worker_number: 2
ThreadPool::start_worker(): stop: t, tasks: 0, worker_number: 1
ThreadPool::start_worker(): workers vector empty. worker_number: 1
~Initializer(): Calling delete InitializerImpl::instance 0x64bbd90
destroy_default_context::~destroy_default_context(): Calling delete default_context 0x64bcb90
ThreadPoolHolder::~ThreadPoolHolder(): Calling delete of thread_pool (nil)
threadCleanup(): Calling delete ptd 0x64bbe50
==1831446==
==1831446== HEAP SUMMARY:
==1831446== in use at exit: 632 bytes in 3 blocks
==1831446== total heap usage: 616 allocs, 613 frees, 133,939 bytes allocated
==1831446==
==1831446== 24 bytes in 1 blocks are still reachable in loss record 1 of 2
==1831446== at 0x4C327EF: operator new(unsigned long) (vg_replace_malloc.c:483)
==1831446== by 0x4F1A330: std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> > std::thread::_S_make_state<std::thread::_Invoker<std::tuple<progschj::ThreadPool::start_worker(unsigned long, std::unique_lock<std::mutex> const&)::{lambda()#1}> > >(std::thread::_Invoker<std::tuple<progschj::ThreadPool::start_worker(unsigned long, std::unique_lock<std::mutex> const&)::{lambda()#1}> >&&) (thread:207)
==1831446== by 0x4F18C9E: std::thread::thread<progschj::ThreadPool::start_worker(unsigned long, std::unique_lock<std::mutex> const&)::{lambda()#1}&, , void>(progschj::ThreadPool::start_worker(unsigned long, std::unique_lock<std::mutex> const&)::{lambda()#1}&) (thread:131)
==1831446== by 0x4F1790C: progschj::ThreadPool::start_worker(unsigned long, std::unique_lock<std::mutex> const&) (ThreadPool.h:342)
==1831446== by 0x4F16EF2: progschj::ThreadPool::ThreadPool(unsigned long) (ThreadPool.h:134)
==1831446== by 0x4F0F31E: log4cplus::(anonymous namespace)::instantiate_thread_pool() (global-init.cxx:145)
==1831446== by 0x4F0F404: log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}::operator()() const (global-init.cxx:201)
==1831446== by 0x4F113A4: void std::__invoke_impl<void, log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}>(std::__invoke_other, log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}&&) (invoke.h:60)
==1831446== by 0x4F10BA3: std::__invoke_result<log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}>::type std::__invoke<log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}>(log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}&&) (invoke.h:95)
==1831446== by 0x4F109BA: std::call_once<log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}>(std::once_flag&, log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}&&)::{lambda()#1}::operator()() const (mutex:672)
==1831446== by 0x4F109E4: std::call_once<log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}>(std::once_flag&, log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}&&)::{lambda()#2}::operator()() const (mutex:677)
==1831446== by 0x4F109F5: std::call_once<log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}>(std::once_flag&, log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}&&)::{lambda()#2}::_FUN() (mutex:677)
==1831446== by 0x6299CD6: __pthread_once_slow (in /usr/lib64/libpthread-2.28.so)
==1831446== by 0x4F0F0F6: __gthread_once(int*, void (*)()) (gthr-default.h:699)
==1831446== by 0x4F10A7B: void std::call_once<log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}>(std::once_flag&, log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}&&) (mutex:684)
==1831446==
==1831446== 608 bytes in 2 blocks are possibly lost in loss record 2 of 2
==1831446== at 0x4C396D7: calloc (vg_replace_malloc.c:1595)
==1831446== by 0x4012421: allocate_dtv (in /usr/lib64/ld-2.28.so)
==1831446== by 0x4012DB1: _dl_allocate_tls (in /usr/lib64/ld-2.28.so)
==1831446== by 0x6292DA2: pthread_create@@GLIBC_2.2.5 (in /usr/lib64/libpthread-2.28.so)
==1831446== by 0x5452E88: std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (in /usr/lib64/libstdc++.so.6.0.25)
==1831446== by 0x4F18CB5: std::thread::thread<progschj::ThreadPool::start_worker(unsigned long, std::unique_lock<std::mutex> const&)::{lambda()#1}&, , void>(progschj::ThreadPool::start_worker(unsigned long, std::unique_lock<std::mutex> const&)::{lambda()#1}&) (thread:131)
==1831446== by 0x4F1790C: progschj::ThreadPool::start_worker(unsigned long, std::unique_lock<std::mutex> const&) (ThreadPool.h:342)
==1831446== by 0x4F16EF2: progschj::ThreadPool::ThreadPool(unsigned long) (ThreadPool.h:134)
==1831446== by 0x4F0F31E: log4cplus::(anonymous namespace)::instantiate_thread_pool() (global-init.cxx:145)
==1831446== by 0x4F0F404: log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}::operator()() const (global-init.cxx:201)
==1831446== by 0x4F113A4: void std::__invoke_impl<void, log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}>(std::__invoke_other, log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}&&) (invoke.h:60)
==1831446== by 0x4F10BA3: std::__invoke_result<log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}>::type std::__invoke<log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}>(log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}&&) (invoke.h:95)
==1831446== by 0x4F109BA: std::call_once<log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}>(std::once_flag&, log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}&&)::{lambda()#1}::operator()() const (mutex:672)
==1831446== by 0x4F109E4: std::call_once<log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}>(std::once_flag&, log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}&&)::{lambda()#2}::operator()() const (mutex:677)
==1831446== by 0x4F109F5: std::call_once<log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}>(std::once_flag&, log4cplus::(anonymous namespace)::DefaultContext::get_thread_pool(bool)::{lambda()#1}&&)::{lambda()#2}::_FUN() (mutex:677)
==1831446==
==1831446== LEAK SUMMARY:
==1831446== definitely lost: 0 bytes in 0 blocks
==1831446== indirectly lost: 0 bytes in 0 blocks
==1831446== possibly lost: 608 bytes in 2 blocks
==1831446== still reachable: 24 bytes in 1 blocks
==1831446== suppressed: 0 bytes in 0 blocks
==1831446==
==1831446== For lists of detected and suppressed errors, rerun with: -s
==1831446== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Metadata
Metadata
Assignees
Labels
No labels