How to correctly exit from a program, which uses Boost Log?
The sample program below works fine, but the valgrind shows, that 520 bytes in 6 blocks are still reachable after exit.
#include <iostream>
#include <string>
#include <boost/log/common.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/phoenix/bind/bind_member_function.hpp>
#include <boost/shared_ptr.hpp>
namespace bl = boost::log;
namespace bp = boost::phoenix;
enum class MySeverityLevel
{
panic,
alert,
critical,
error,
warning,
notice,
info,
debug
};
BOOST_LOG_ATTRIBUTE_KEYWORD(Severity, "Severity", MySeverityLevel)
BOOST_LOG_ATTRIBUTE_KEYWORD(Channel, "Channel", std::string)
class Logger
{
public:
Logger(const std::string& CH, const MySeverityLevel SEV):
m_log(bl::keywords::channel = CH), m_channel(CH), m_severityMax(SEV)
{
m_sink = bl::add_file_log
(
bl::keywords::file_name = CH + ".log",
bl::keywords::filter = bp::bind(&Logger::filter, this, Channel.or_none(), Severity.or_none())
);
}
~Logger()
{
this->terminate();
}
void terminate()
{
if (m_sink)
{
bl::core::get()->remove_sink(m_sink);
m_sink->flush();
m_sink.reset();
}
}
void panic(const std::string& S)
{
BOOST_LOG_SEV(m_log, MySeverityLevel::panic) << S;
}
void debug(const std::string& S)
{
BOOST_LOG_SEV(m_log, MySeverityLevel::debug) << S;
}
private:
using ChannelValue = bl::value_ref<std::string, tag::Channel>;
using MySeverityLevelValue = bl::value_ref<MySeverityLevel, tag::Severity>;
bool filter(const ChannelValue& CH, const MySeverityLevelValue& SEV) const
{
if (CH && SEV)
{
return (CH.get() == m_channel) && (SEV.get() <= m_severityMax);
}
else
{
return false;
}
}
bl::sources::severity_channel_logger<MySeverityLevel, std::string> m_log;
boost::shared_ptr<bl::sinks::sink> m_sink;
const std::string m_channel;
const MySeverityLevel m_severityMax;
};
int main()
{
Logger lgA("A", MySeverityLevel::error);
lgA.panic("A: Panic");
lgA.debug("A: Debug");
lgA.terminate();
}
That's the valgrind output:
hekto@ubuntu:~$ valgrind --leak-check=full --show-leak-kinds=all ./tc0013
==48934== Memcheck, a memory error detector
==48934== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==48934== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==48934== Command: ./tc0013
==48934==
==48934==
==48934== HEAP SUMMARY:
==48934== in use at exit: 520 bytes in 6 blocks
==48934== total heap usage: 83 allocs, 77 frees, 97,276 bytes allocated
==48934==
==48934== 8 bytes in 1 blocks are still reachable in loss record 1 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x4E98C61: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 8 bytes in 1 blocks are still reachable in loss record 2 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x4E9EF69: boost::log::v2_mt_posix::aux::this_thread::get_id() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x4E8BB96: boost::log::v2_mt_posix::core::open_record(boost::log::v2_mt_posix::attribute_set const&) (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x118DEA: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:259)
==48934== by 0x11825B: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::open_record_with_channel_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&, boost::parameter::void_) (channel_feature.hpp:195)
==48934== by 0x1172B2: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (channel_feature.hpp:171)
==48934== by 0x115E8B: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:253)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 16 bytes in 1 blocks are still reachable in loss record 3 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x512A5BA: boost::detail::add_thread_exit_function(boost::detail::thread_exit_function_base*) (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x4E98C9A: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 24 bytes in 1 blocks are still reachable in loss record 4 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x4E98C84: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 24 bytes in 1 blocks are still reachable in loss record 5 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x512A1BC: boost::detail::make_external_thread_data() (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x512A5AD: boost::detail::add_thread_exit_function(boost::detail::thread_exit_function_base*) (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x4E98C9A: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 440 bytes in 1 blocks are still reachable in loss record 6 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x512A03D: boost::detail::make_external_thread_data() (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x512A5AD: boost::detail::add_thread_exit_function(boost::detail::thread_exit_function_base*) (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x4E98C9A: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== LEAK SUMMARY:
==48934== definitely lost: 0 bytes in 0 blocks
==48934== indirectly lost: 0 bytes in 0 blocks
==48934== possibly lost: 0 bytes in 0 blocks
==48934== still reachable: 520 bytes in 6 blocks
==48934== suppressed: 0 bytes in 0 blocks
==48934==
==48934== For counts of detected and suppressed errors, rerun with: -v
==48934== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
In my real application the Logger class lives in a library, that's why I need to properly terminate it (the termination is performed by the systemctl). However, I still see exceptions in syslog during the exit from my application:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::log::v2_mt_posix::system_error> >'
I think that finding a way to get rid of these "520 bytes in 6 blocks" after exit will help me to terminate my application clearly.
How to write the terminate function (see above) correctly - in order not to leave anything in Boost Log internals reachable?
- OS: Ubuntu 18.04.1 LTS
- Compiler: g++ 7.3.0
- Boost: 1.65.1
- Valgrind: 3.13.0
c++ boost-log
add a comment |
The sample program below works fine, but the valgrind shows, that 520 bytes in 6 blocks are still reachable after exit.
#include <iostream>
#include <string>
#include <boost/log/common.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/phoenix/bind/bind_member_function.hpp>
#include <boost/shared_ptr.hpp>
namespace bl = boost::log;
namespace bp = boost::phoenix;
enum class MySeverityLevel
{
panic,
alert,
critical,
error,
warning,
notice,
info,
debug
};
BOOST_LOG_ATTRIBUTE_KEYWORD(Severity, "Severity", MySeverityLevel)
BOOST_LOG_ATTRIBUTE_KEYWORD(Channel, "Channel", std::string)
class Logger
{
public:
Logger(const std::string& CH, const MySeverityLevel SEV):
m_log(bl::keywords::channel = CH), m_channel(CH), m_severityMax(SEV)
{
m_sink = bl::add_file_log
(
bl::keywords::file_name = CH + ".log",
bl::keywords::filter = bp::bind(&Logger::filter, this, Channel.or_none(), Severity.or_none())
);
}
~Logger()
{
this->terminate();
}
void terminate()
{
if (m_sink)
{
bl::core::get()->remove_sink(m_sink);
m_sink->flush();
m_sink.reset();
}
}
void panic(const std::string& S)
{
BOOST_LOG_SEV(m_log, MySeverityLevel::panic) << S;
}
void debug(const std::string& S)
{
BOOST_LOG_SEV(m_log, MySeverityLevel::debug) << S;
}
private:
using ChannelValue = bl::value_ref<std::string, tag::Channel>;
using MySeverityLevelValue = bl::value_ref<MySeverityLevel, tag::Severity>;
bool filter(const ChannelValue& CH, const MySeverityLevelValue& SEV) const
{
if (CH && SEV)
{
return (CH.get() == m_channel) && (SEV.get() <= m_severityMax);
}
else
{
return false;
}
}
bl::sources::severity_channel_logger<MySeverityLevel, std::string> m_log;
boost::shared_ptr<bl::sinks::sink> m_sink;
const std::string m_channel;
const MySeverityLevel m_severityMax;
};
int main()
{
Logger lgA("A", MySeverityLevel::error);
lgA.panic("A: Panic");
lgA.debug("A: Debug");
lgA.terminate();
}
That's the valgrind output:
hekto@ubuntu:~$ valgrind --leak-check=full --show-leak-kinds=all ./tc0013
==48934== Memcheck, a memory error detector
==48934== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==48934== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==48934== Command: ./tc0013
==48934==
==48934==
==48934== HEAP SUMMARY:
==48934== in use at exit: 520 bytes in 6 blocks
==48934== total heap usage: 83 allocs, 77 frees, 97,276 bytes allocated
==48934==
==48934== 8 bytes in 1 blocks are still reachable in loss record 1 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x4E98C61: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 8 bytes in 1 blocks are still reachable in loss record 2 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x4E9EF69: boost::log::v2_mt_posix::aux::this_thread::get_id() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x4E8BB96: boost::log::v2_mt_posix::core::open_record(boost::log::v2_mt_posix::attribute_set const&) (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x118DEA: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:259)
==48934== by 0x11825B: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::open_record_with_channel_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&, boost::parameter::void_) (channel_feature.hpp:195)
==48934== by 0x1172B2: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (channel_feature.hpp:171)
==48934== by 0x115E8B: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:253)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 16 bytes in 1 blocks are still reachable in loss record 3 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x512A5BA: boost::detail::add_thread_exit_function(boost::detail::thread_exit_function_base*) (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x4E98C9A: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 24 bytes in 1 blocks are still reachable in loss record 4 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x4E98C84: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 24 bytes in 1 blocks are still reachable in loss record 5 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x512A1BC: boost::detail::make_external_thread_data() (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x512A5AD: boost::detail::add_thread_exit_function(boost::detail::thread_exit_function_base*) (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x4E98C9A: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 440 bytes in 1 blocks are still reachable in loss record 6 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x512A03D: boost::detail::make_external_thread_data() (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x512A5AD: boost::detail::add_thread_exit_function(boost::detail::thread_exit_function_base*) (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x4E98C9A: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== LEAK SUMMARY:
==48934== definitely lost: 0 bytes in 0 blocks
==48934== indirectly lost: 0 bytes in 0 blocks
==48934== possibly lost: 0 bytes in 0 blocks
==48934== still reachable: 520 bytes in 6 blocks
==48934== suppressed: 0 bytes in 0 blocks
==48934==
==48934== For counts of detected and suppressed errors, rerun with: -v
==48934== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
In my real application the Logger class lives in a library, that's why I need to properly terminate it (the termination is performed by the systemctl). However, I still see exceptions in syslog during the exit from my application:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::log::v2_mt_posix::system_error> >'
I think that finding a way to get rid of these "520 bytes in 6 blocks" after exit will help me to terminate my application clearly.
How to write the terminate function (see above) correctly - in order not to leave anything in Boost Log internals reachable?
- OS: Ubuntu 18.04.1 LTS
- Compiler: g++ 7.3.0
- Boost: 1.65.1
- Valgrind: 3.13.0
c++ boost-log
If you are asking about "520 bytes in 6 blocks" then you should post stack traces for the problematic allocations (that is complete valgrind output) and also list system / compiler / valgrind / boost versions used. If you are asking about "real application" then you should post a real code causing the stated exception.
– VTT
Jan 3 at 7:39
@VTT - done, thanks
– HEKTO
Jan 3 at 17:46
add a comment |
The sample program below works fine, but the valgrind shows, that 520 bytes in 6 blocks are still reachable after exit.
#include <iostream>
#include <string>
#include <boost/log/common.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/phoenix/bind/bind_member_function.hpp>
#include <boost/shared_ptr.hpp>
namespace bl = boost::log;
namespace bp = boost::phoenix;
enum class MySeverityLevel
{
panic,
alert,
critical,
error,
warning,
notice,
info,
debug
};
BOOST_LOG_ATTRIBUTE_KEYWORD(Severity, "Severity", MySeverityLevel)
BOOST_LOG_ATTRIBUTE_KEYWORD(Channel, "Channel", std::string)
class Logger
{
public:
Logger(const std::string& CH, const MySeverityLevel SEV):
m_log(bl::keywords::channel = CH), m_channel(CH), m_severityMax(SEV)
{
m_sink = bl::add_file_log
(
bl::keywords::file_name = CH + ".log",
bl::keywords::filter = bp::bind(&Logger::filter, this, Channel.or_none(), Severity.or_none())
);
}
~Logger()
{
this->terminate();
}
void terminate()
{
if (m_sink)
{
bl::core::get()->remove_sink(m_sink);
m_sink->flush();
m_sink.reset();
}
}
void panic(const std::string& S)
{
BOOST_LOG_SEV(m_log, MySeverityLevel::panic) << S;
}
void debug(const std::string& S)
{
BOOST_LOG_SEV(m_log, MySeverityLevel::debug) << S;
}
private:
using ChannelValue = bl::value_ref<std::string, tag::Channel>;
using MySeverityLevelValue = bl::value_ref<MySeverityLevel, tag::Severity>;
bool filter(const ChannelValue& CH, const MySeverityLevelValue& SEV) const
{
if (CH && SEV)
{
return (CH.get() == m_channel) && (SEV.get() <= m_severityMax);
}
else
{
return false;
}
}
bl::sources::severity_channel_logger<MySeverityLevel, std::string> m_log;
boost::shared_ptr<bl::sinks::sink> m_sink;
const std::string m_channel;
const MySeverityLevel m_severityMax;
};
int main()
{
Logger lgA("A", MySeverityLevel::error);
lgA.panic("A: Panic");
lgA.debug("A: Debug");
lgA.terminate();
}
That's the valgrind output:
hekto@ubuntu:~$ valgrind --leak-check=full --show-leak-kinds=all ./tc0013
==48934== Memcheck, a memory error detector
==48934== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==48934== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==48934== Command: ./tc0013
==48934==
==48934==
==48934== HEAP SUMMARY:
==48934== in use at exit: 520 bytes in 6 blocks
==48934== total heap usage: 83 allocs, 77 frees, 97,276 bytes allocated
==48934==
==48934== 8 bytes in 1 blocks are still reachable in loss record 1 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x4E98C61: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 8 bytes in 1 blocks are still reachable in loss record 2 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x4E9EF69: boost::log::v2_mt_posix::aux::this_thread::get_id() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x4E8BB96: boost::log::v2_mt_posix::core::open_record(boost::log::v2_mt_posix::attribute_set const&) (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x118DEA: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:259)
==48934== by 0x11825B: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::open_record_with_channel_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&, boost::parameter::void_) (channel_feature.hpp:195)
==48934== by 0x1172B2: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (channel_feature.hpp:171)
==48934== by 0x115E8B: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:253)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 16 bytes in 1 blocks are still reachable in loss record 3 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x512A5BA: boost::detail::add_thread_exit_function(boost::detail::thread_exit_function_base*) (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x4E98C9A: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 24 bytes in 1 blocks are still reachable in loss record 4 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x4E98C84: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 24 bytes in 1 blocks are still reachable in loss record 5 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x512A1BC: boost::detail::make_external_thread_data() (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x512A5AD: boost::detail::add_thread_exit_function(boost::detail::thread_exit_function_base*) (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x4E98C9A: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 440 bytes in 1 blocks are still reachable in loss record 6 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x512A03D: boost::detail::make_external_thread_data() (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x512A5AD: boost::detail::add_thread_exit_function(boost::detail::thread_exit_function_base*) (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x4E98C9A: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== LEAK SUMMARY:
==48934== definitely lost: 0 bytes in 0 blocks
==48934== indirectly lost: 0 bytes in 0 blocks
==48934== possibly lost: 0 bytes in 0 blocks
==48934== still reachable: 520 bytes in 6 blocks
==48934== suppressed: 0 bytes in 0 blocks
==48934==
==48934== For counts of detected and suppressed errors, rerun with: -v
==48934== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
In my real application the Logger class lives in a library, that's why I need to properly terminate it (the termination is performed by the systemctl). However, I still see exceptions in syslog during the exit from my application:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::log::v2_mt_posix::system_error> >'
I think that finding a way to get rid of these "520 bytes in 6 blocks" after exit will help me to terminate my application clearly.
How to write the terminate function (see above) correctly - in order not to leave anything in Boost Log internals reachable?
- OS: Ubuntu 18.04.1 LTS
- Compiler: g++ 7.3.0
- Boost: 1.65.1
- Valgrind: 3.13.0
c++ boost-log
The sample program below works fine, but the valgrind shows, that 520 bytes in 6 blocks are still reachable after exit.
#include <iostream>
#include <string>
#include <boost/log/common.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/phoenix/bind/bind_member_function.hpp>
#include <boost/shared_ptr.hpp>
namespace bl = boost::log;
namespace bp = boost::phoenix;
enum class MySeverityLevel
{
panic,
alert,
critical,
error,
warning,
notice,
info,
debug
};
BOOST_LOG_ATTRIBUTE_KEYWORD(Severity, "Severity", MySeverityLevel)
BOOST_LOG_ATTRIBUTE_KEYWORD(Channel, "Channel", std::string)
class Logger
{
public:
Logger(const std::string& CH, const MySeverityLevel SEV):
m_log(bl::keywords::channel = CH), m_channel(CH), m_severityMax(SEV)
{
m_sink = bl::add_file_log
(
bl::keywords::file_name = CH + ".log",
bl::keywords::filter = bp::bind(&Logger::filter, this, Channel.or_none(), Severity.or_none())
);
}
~Logger()
{
this->terminate();
}
void terminate()
{
if (m_sink)
{
bl::core::get()->remove_sink(m_sink);
m_sink->flush();
m_sink.reset();
}
}
void panic(const std::string& S)
{
BOOST_LOG_SEV(m_log, MySeverityLevel::panic) << S;
}
void debug(const std::string& S)
{
BOOST_LOG_SEV(m_log, MySeverityLevel::debug) << S;
}
private:
using ChannelValue = bl::value_ref<std::string, tag::Channel>;
using MySeverityLevelValue = bl::value_ref<MySeverityLevel, tag::Severity>;
bool filter(const ChannelValue& CH, const MySeverityLevelValue& SEV) const
{
if (CH && SEV)
{
return (CH.get() == m_channel) && (SEV.get() <= m_severityMax);
}
else
{
return false;
}
}
bl::sources::severity_channel_logger<MySeverityLevel, std::string> m_log;
boost::shared_ptr<bl::sinks::sink> m_sink;
const std::string m_channel;
const MySeverityLevel m_severityMax;
};
int main()
{
Logger lgA("A", MySeverityLevel::error);
lgA.panic("A: Panic");
lgA.debug("A: Debug");
lgA.terminate();
}
That's the valgrind output:
hekto@ubuntu:~$ valgrind --leak-check=full --show-leak-kinds=all ./tc0013
==48934== Memcheck, a memory error detector
==48934== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==48934== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==48934== Command: ./tc0013
==48934==
==48934==
==48934== HEAP SUMMARY:
==48934== in use at exit: 520 bytes in 6 blocks
==48934== total heap usage: 83 allocs, 77 frees, 97,276 bytes allocated
==48934==
==48934== 8 bytes in 1 blocks are still reachable in loss record 1 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x4E98C61: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 8 bytes in 1 blocks are still reachable in loss record 2 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x4E9EF69: boost::log::v2_mt_posix::aux::this_thread::get_id() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x4E8BB96: boost::log::v2_mt_posix::core::open_record(boost::log::v2_mt_posix::attribute_set const&) (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x118DEA: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:259)
==48934== by 0x11825B: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::open_record_with_channel_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&, boost::parameter::void_) (channel_feature.hpp:195)
==48934== by 0x1172B2: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (channel_feature.hpp:171)
==48934== by 0x115E8B: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:253)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 16 bytes in 1 blocks are still reachable in loss record 3 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x512A5BA: boost::detail::add_thread_exit_function(boost::detail::thread_exit_function_base*) (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x4E98C9A: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 24 bytes in 1 blocks are still reachable in loss record 4 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x4E98C84: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 24 bytes in 1 blocks are still reachable in loss record 5 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x512A1BC: boost::detail::make_external_thread_data() (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x512A5AD: boost::detail::add_thread_exit_function(boost::detail::thread_exit_function_base*) (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x4E98C9A: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== 440 bytes in 1 blocks are still reachable in loss record 6 of 6
==48934== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48934== by 0x512A03D: boost::detail::make_external_thread_data() (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x512A5AD: boost::detail::add_thread_exit_function(boost::detail::thread_exit_function_base*) (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1)
==48934== by 0x4E98C9A: boost::log::v2_mt_posix::sources::aux::get_severity_level() (in /usr/lib/x86_64-linux-gnu/libboost_log.so.1.65.1)
==48934== by 0x11723B: boost::log::v2_mt_posix::sources::aux::severity_level<MySeverityLevel>::set_value(MySeverityLevel) (severity_feature.hpp:135)
==48934== by 0x115E74: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_severity_logger<boost::log::v2_mt_posix::sources::basic_channel_logger<boost::log::v2_mt_posix::sources::basic_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MySeverityLevel>::open_record_unlocked<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (severity_feature.hpp:252)
==48934== by 0x114961: boost::log::v2_mt_posix::record boost::log::v2_mt_posix::sources::basic_composite_logger<char, boost::log::v2_mt_posix::sources::severity_channel_logger<MySeverityLevel, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::log::v2_mt_posix::sources::single_thread_model, boost::log::v2_mt_posix::sources::features<boost::log::v2_mt_posix::sources::severity<MySeverityLevel>, boost::log::v2_mt_posix::sources::channel<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::open_record<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> >(boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, MySeverityLevel const> const&) (basic_logger.hpp:575)
==48934== by 0x1135A5: Logger::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tc0013.cpp:81)
==48934== by 0x11097B: main (tc0013.cpp:120)
==48934==
==48934== LEAK SUMMARY:
==48934== definitely lost: 0 bytes in 0 blocks
==48934== indirectly lost: 0 bytes in 0 blocks
==48934== possibly lost: 0 bytes in 0 blocks
==48934== still reachable: 520 bytes in 6 blocks
==48934== suppressed: 0 bytes in 0 blocks
==48934==
==48934== For counts of detected and suppressed errors, rerun with: -v
==48934== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
In my real application the Logger class lives in a library, that's why I need to properly terminate it (the termination is performed by the systemctl). However, I still see exceptions in syslog during the exit from my application:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::log::v2_mt_posix::system_error> >'
I think that finding a way to get rid of these "520 bytes in 6 blocks" after exit will help me to terminate my application clearly.
How to write the terminate function (see above) correctly - in order not to leave anything in Boost Log internals reachable?
- OS: Ubuntu 18.04.1 LTS
- Compiler: g++ 7.3.0
- Boost: 1.65.1
- Valgrind: 3.13.0
c++ boost-log
c++ boost-log
edited Jan 3 at 17:24
HEKTO
asked Jan 3 at 5:32
HEKTOHEKTO
1,99511532
1,99511532
If you are asking about "520 bytes in 6 blocks" then you should post stack traces for the problematic allocations (that is complete valgrind output) and also list system / compiler / valgrind / boost versions used. If you are asking about "real application" then you should post a real code causing the stated exception.
– VTT
Jan 3 at 7:39
@VTT - done, thanks
– HEKTO
Jan 3 at 17:46
add a comment |
If you are asking about "520 bytes in 6 blocks" then you should post stack traces for the problematic allocations (that is complete valgrind output) and also list system / compiler / valgrind / boost versions used. If you are asking about "real application" then you should post a real code causing the stated exception.
– VTT
Jan 3 at 7:39
@VTT - done, thanks
– HEKTO
Jan 3 at 17:46
If you are asking about "520 bytes in 6 blocks" then you should post stack traces for the problematic allocations (that is complete valgrind output) and also list system / compiler / valgrind / boost versions used. If you are asking about "real application" then you should post a real code causing the stated exception.
– VTT
Jan 3 at 7:39
If you are asking about "520 bytes in 6 blocks" then you should post stack traces for the problematic allocations (that is complete valgrind output) and also list system / compiler / valgrind / boost versions used. If you are asking about "real application" then you should post a real code causing the stated exception.
– VTT
Jan 3 at 7:39
@VTT - done, thanks
– HEKTO
Jan 3 at 17:46
@VTT - done, thanks
– HEKTO
Jan 3 at 17:46
add a comment |
1 Answer
1
active
oldest
votes
tl;dr; boost.log is hopelessly doomed, use something else...
The peculiar detail in these call stacks is repeating invocation of boost::detail::add_thread_exit_function which is implementation of boost::this_thread::at_thread_exit that is obviously used to perform some cleanup actions when thread is about to end. However this function can not be used with system-specific thread ending APIs and functions such as exit. As stated in the docs:
In particular, returning from main() is equivalent to call to exit(), so will not call any functions registered with at_thread_exit()
So boost.log does not perform any cleanup when being invoked from main thread. Moreover, (among other ugly things) boost.log uses Meyer's singleton to hold an instance of core context, so library users have no control over lifetime of core context (and objects owned by it) and are prone to static [un]initialization order fiasco.
Thank you! So - singleton in shared library is evil... I asked a question about MongoDB context (stackoverflow.com/questions/50914898/…) last year, and a leading engineer from MongoDB has recommended me to use just that - a Meyer singleton in a shared library (github.com/mongodb/mongo-cxx-driver/blob/r3.3.0/examples/…). Could you please comment on this? (It's much shorter)))
– HEKTO
Jan 5 at 17:19
@HEKTO It is not that singleton is evil, it is that it is [un]initialized implicitly with no control over object lifetime from programmer. I guess one should not expect much from some minimal examples. Another somewhat related question with interesting discussion: Force construction of a global object
– VTT
Jan 5 at 22:23
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54016819%2fhow-to-correctly-exit-from-a-program-which-uses-boost-log%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
tl;dr; boost.log is hopelessly doomed, use something else...
The peculiar detail in these call stacks is repeating invocation of boost::detail::add_thread_exit_function which is implementation of boost::this_thread::at_thread_exit that is obviously used to perform some cleanup actions when thread is about to end. However this function can not be used with system-specific thread ending APIs and functions such as exit. As stated in the docs:
In particular, returning from main() is equivalent to call to exit(), so will not call any functions registered with at_thread_exit()
So boost.log does not perform any cleanup when being invoked from main thread. Moreover, (among other ugly things) boost.log uses Meyer's singleton to hold an instance of core context, so library users have no control over lifetime of core context (and objects owned by it) and are prone to static [un]initialization order fiasco.
Thank you! So - singleton in shared library is evil... I asked a question about MongoDB context (stackoverflow.com/questions/50914898/…) last year, and a leading engineer from MongoDB has recommended me to use just that - a Meyer singleton in a shared library (github.com/mongodb/mongo-cxx-driver/blob/r3.3.0/examples/…). Could you please comment on this? (It's much shorter)))
– HEKTO
Jan 5 at 17:19
@HEKTO It is not that singleton is evil, it is that it is [un]initialized implicitly with no control over object lifetime from programmer. I guess one should not expect much from some minimal examples. Another somewhat related question with interesting discussion: Force construction of a global object
– VTT
Jan 5 at 22:23
add a comment |
tl;dr; boost.log is hopelessly doomed, use something else...
The peculiar detail in these call stacks is repeating invocation of boost::detail::add_thread_exit_function which is implementation of boost::this_thread::at_thread_exit that is obviously used to perform some cleanup actions when thread is about to end. However this function can not be used with system-specific thread ending APIs and functions such as exit. As stated in the docs:
In particular, returning from main() is equivalent to call to exit(), so will not call any functions registered with at_thread_exit()
So boost.log does not perform any cleanup when being invoked from main thread. Moreover, (among other ugly things) boost.log uses Meyer's singleton to hold an instance of core context, so library users have no control over lifetime of core context (and objects owned by it) and are prone to static [un]initialization order fiasco.
Thank you! So - singleton in shared library is evil... I asked a question about MongoDB context (stackoverflow.com/questions/50914898/…) last year, and a leading engineer from MongoDB has recommended me to use just that - a Meyer singleton in a shared library (github.com/mongodb/mongo-cxx-driver/blob/r3.3.0/examples/…). Could you please comment on this? (It's much shorter)))
– HEKTO
Jan 5 at 17:19
@HEKTO It is not that singleton is evil, it is that it is [un]initialized implicitly with no control over object lifetime from programmer. I guess one should not expect much from some minimal examples. Another somewhat related question with interesting discussion: Force construction of a global object
– VTT
Jan 5 at 22:23
add a comment |
tl;dr; boost.log is hopelessly doomed, use something else...
The peculiar detail in these call stacks is repeating invocation of boost::detail::add_thread_exit_function which is implementation of boost::this_thread::at_thread_exit that is obviously used to perform some cleanup actions when thread is about to end. However this function can not be used with system-specific thread ending APIs and functions such as exit. As stated in the docs:
In particular, returning from main() is equivalent to call to exit(), so will not call any functions registered with at_thread_exit()
So boost.log does not perform any cleanup when being invoked from main thread. Moreover, (among other ugly things) boost.log uses Meyer's singleton to hold an instance of core context, so library users have no control over lifetime of core context (and objects owned by it) and are prone to static [un]initialization order fiasco.
tl;dr; boost.log is hopelessly doomed, use something else...
The peculiar detail in these call stacks is repeating invocation of boost::detail::add_thread_exit_function which is implementation of boost::this_thread::at_thread_exit that is obviously used to perform some cleanup actions when thread is about to end. However this function can not be used with system-specific thread ending APIs and functions such as exit. As stated in the docs:
In particular, returning from main() is equivalent to call to exit(), so will not call any functions registered with at_thread_exit()
So boost.log does not perform any cleanup when being invoked from main thread. Moreover, (among other ugly things) boost.log uses Meyer's singleton to hold an instance of core context, so library users have no control over lifetime of core context (and objects owned by it) and are prone to static [un]initialization order fiasco.
answered Jan 3 at 22:50
VTTVTT
25.6k42448
25.6k42448
Thank you! So - singleton in shared library is evil... I asked a question about MongoDB context (stackoverflow.com/questions/50914898/…) last year, and a leading engineer from MongoDB has recommended me to use just that - a Meyer singleton in a shared library (github.com/mongodb/mongo-cxx-driver/blob/r3.3.0/examples/…). Could you please comment on this? (It's much shorter)))
– HEKTO
Jan 5 at 17:19
@HEKTO It is not that singleton is evil, it is that it is [un]initialized implicitly with no control over object lifetime from programmer. I guess one should not expect much from some minimal examples. Another somewhat related question with interesting discussion: Force construction of a global object
– VTT
Jan 5 at 22:23
add a comment |
Thank you! So - singleton in shared library is evil... I asked a question about MongoDB context (stackoverflow.com/questions/50914898/…) last year, and a leading engineer from MongoDB has recommended me to use just that - a Meyer singleton in a shared library (github.com/mongodb/mongo-cxx-driver/blob/r3.3.0/examples/…). Could you please comment on this? (It's much shorter)))
– HEKTO
Jan 5 at 17:19
@HEKTO It is not that singleton is evil, it is that it is [un]initialized implicitly with no control over object lifetime from programmer. I guess one should not expect much from some minimal examples. Another somewhat related question with interesting discussion: Force construction of a global object
– VTT
Jan 5 at 22:23
Thank you! So - singleton in shared library is evil... I asked a question about MongoDB context (stackoverflow.com/questions/50914898/…) last year, and a leading engineer from MongoDB has recommended me to use just that - a Meyer singleton in a shared library (github.com/mongodb/mongo-cxx-driver/blob/r3.3.0/examples/…). Could you please comment on this? (It's much shorter)))
– HEKTO
Jan 5 at 17:19
Thank you! So - singleton in shared library is evil... I asked a question about MongoDB context (stackoverflow.com/questions/50914898/…) last year, and a leading engineer from MongoDB has recommended me to use just that - a Meyer singleton in a shared library (github.com/mongodb/mongo-cxx-driver/blob/r3.3.0/examples/…). Could you please comment on this? (It's much shorter)))
– HEKTO
Jan 5 at 17:19
@HEKTO It is not that singleton is evil, it is that it is [un]initialized implicitly with no control over object lifetime from programmer. I guess one should not expect much from some minimal examples. Another somewhat related question with interesting discussion: Force construction of a global object
– VTT
Jan 5 at 22:23
@HEKTO It is not that singleton is evil, it is that it is [un]initialized implicitly with no control over object lifetime from programmer. I guess one should not expect much from some minimal examples. Another somewhat related question with interesting discussion: Force construction of a global object
– VTT
Jan 5 at 22:23
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54016819%2fhow-to-correctly-exit-from-a-program-which-uses-boost-log%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
If you are asking about "520 bytes in 6 blocks" then you should post stack traces for the problematic allocations (that is complete valgrind output) and also list system / compiler / valgrind / boost versions used. If you are asking about "real application" then you should post a real code causing the stated exception.
– VTT
Jan 3 at 7:39
@VTT - done, thanks
– HEKTO
Jan 3 at 17:46