c++boostgcc6

Issues with Boost using fsanitize switch in gcc


I have been trying to take advantage of some of the GCC Instrumentation Options for runtime-checking to try and debug/diagnose issues I am having in a particular region of C++ code.

To try and narrow down the problem, I started enabling some of these features, but errors were encountered in regions of code that I was not expecting - namely in the Boost library.

When I use the gcc switch '-fsanitize=undefined', I notice that there are a number of runtime errors that are reported by gdb; I seem to be able to reproduce these errors with very little effort. I have provided some sample code below.

Environment Configuration:

The sample code is as follows:

// $TEST_BEGIN_HEADER$                                                    //
// $TEST_END_HEADER$                                                      //


// Libraries
#include <boost/log/trivial.hpp>

// Test Headers

// Forward Declarations



typedef boost::log::sources::wseverity_logger_mt< boost::log::trivial::severity_level>   test_mt_wlogger;

#define TEST_LOG_TRACE(lg)        BOOST_LOG_SEV(lg, boost::log::trivial::trace)
#define TEST_LOG_DEBUG(lg)        BOOST_LOG_SEV(lg, boost::log::trivial::debug)
#define TEST_LOG_INFO(lg)         BOOST_LOG_SEV(lg, boost::log::trivial::info)
#define TEST_LOG_WARNING(lg)      BOOST_LOG_SEV(lg, boost::log::trivial::warning)
#define TEST_LOG_ERROR(lg)        BOOST_LOG_SEV(lg, boost::log::trivial::error)
#define TEST_LOG_FATAL(lg)        BOOST_LOG_SEV(lg, boost::log::trivial::fatal)


///////////////////////////////////////////////////////////////////////////
int main(int ac, char* av[])
{
    test_mt_wlogger lg;

    TEST_LOG_INFO(lg) << L"Example!";

    return 0;
}


// $TEST_BEGIN_FOOTER$                                                    //
// $TEST_END_FOOTER$                                                      //

The CMakefile looks like:

cmake_minimum_required (VERSION 3.4)

project(Test)

message(STATUS "Project:    ${PROJECT_NAME}")
message(STATUS "Platform:   ${CMAKE_SYSTEM_NAME} (${CMAKE_SYSTEM})")
message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}")


set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)


add_definitions(/DUNICODE)


# Options added:
# 1. Using C++ 14.
# 2. Increase warning level
# 3. Make all warnings into errors.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -Werror")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=undefined")

################################################################
# Find Thread - used implicitly by GTest
find_package(Threads REQUIRED)

################################################################
# Find Boost.
# This flag may need to change depending on the version of
# Boost installed.
set(Boost_USE_STATIC_LIBS        OFF) # only find static libs
set(Boost_USE_MULTITHREADED      ON)
set(Boost_USE_STATIC_RUNTIME     OFF)

find_package(Boost REQUIRED COMPONENTS thread system chrono log)


# Set the location where our binaries will be stored.
# WARN/TODO: Not quite right, because .lib or .a files should
#            not go in the bin folder!
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

# Adds 'd' onto artifacts - does NOT apply to executables.
# For executables, this needs to be done an exec-by-exec
# basis.
set(CMAKE_DEBUG_POSTFIX "d")


# Additional Include Directories
include_directories(    #Third Party
                        ${Boost_INCLUDE_DIR}

                        #Local Directories
                        )

# Define an executable
add_executable(vt_test
                    main.cpp
        )

# Add postfix onto executable debug filename
set_target_properties(vt_test PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})

add_definitions(-DBOOST_LOG_DYN_LINK)

# Define the libraries this project depends upon
target_link_libraries(vt_test

                        # Local Libraries

                        # Third Party
                        Boost::log )

GDB Sample output:

(gdb) step
/usr/include/boost/log/utility/formatting_ostream.hpp:669:17: runtime error: member call on address 0x55555577c028 which does not point to an object of type 'basic_ostringstreambuf'
0x55555577c028: note: object is of type 'boost::log::v2_mt_posix::aux::basic_ostringstreambuf<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >'
 00 00 00 00  70 3a dd f7 ff 7f 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00
              ^~~~~~~~~~~~~~~~~~~~~~~
              vptr for 'boost::log::v2_mt_posix::aux::basic_ostringstreambuf<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >'
boost::log::v2_mt_posix::aux::basic_ostringstreambuf<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::storage[abi:cxx11]() const (this=0x55555577c028) at /usr/include/boost/log/detail/attachable_sstream_buf.hpp:109
109     string_type* storage() const { return m_Storage; }
(gdb) bt
#0  boost::log::v2_mt_posix::aux::basic_ostringstreambuf<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::storage[abi:cxx11]() const (this=0x55555577c028) at /usr/include/boost/log/detail/attachable_sstream_buf.hpp:109
#1  0x000055555555e172 in boost::log::v2_mt_posix::basic_formatting_ostream<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::formatted_write (this=0x55555577c028, p=0x55555555fb48 L"Example!", size=8) at /usr/include/boost/log/utility/formatting_ostream.hpp:669
#2  0x000055555555d317 in boost::log::v2_mt_posix::basic_formatting_ostream<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::operator<< (this=0x55555577c028, p=0x55555555fb48 L"Example!") at /usr/include/boost/log/utility/formatting_ostream.hpp:416
#3  0x000055555555c4e5 in boost::log::v2_mt_posix::operator<< <boost::log::v2_mt_posix::basic_record_ostream<wchar_t>, wchar_t [9]> (
    strm=..., value=...) at /usr/include/boost/log/sources/record_ostream.hpp:203
#4  0x000055555555a3a2 in main (ac=1, av=0x7fffffffdf68) at /home/user/code/test/main.cpp:31

There were a number of questions that I have gathered together after having some thoughts about my findings:

  1. Is this a coding error?
  2. Does this surprise any of you?
  3. Are these errors false-positives?
  4. Do any of you use the '-fsanitize' switches?
  5. Should I try a newer version of Boost (ie v1.63 built from source)?
  6. Can I install both v1.61 and v1.63 on my system (but only link to one of them)?

Solution

    1. yes
    2. no
    3. no
    4. yes
    5. no (or yes, but not likely directly relevant)
    6. Yes, why? (see also)

    I think your answer (using the crystal ball and not spending time looking at the actual code yet) is probably in here: Boost Thread Access Violation in Boost Log on shutdown