How to correctly exit from a program, which uses Boost Log?












0















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










share|improve this question

























  • 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
















0















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










share|improve this question

























  • 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














0












0








0








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










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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



















  • 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












1 Answer
1






active

oldest

votes


















1














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.






share|improve this answer
























  • 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













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
});


}
});














draft saved

draft discarded


















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









1














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.






share|improve this answer
























  • 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


















1














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.






share|improve this answer
























  • 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
















1












1








1







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.






share|improve this answer













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.







share|improve this answer












share|improve this answer



share|improve this answer










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





















  • 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






















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Mossoró

Error while reading .h5 file using the rhdf5 package in R

Pushsharp Apns notification error: 'InvalidToken'