2

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:

  • Ubuntu v16.10 (Yakkety) x86_x64
  • Boost v1.61 (using apt-get)
  • GCC 6.3.0 (recently built from source but issues occurred with version from apt-get)
  • GDB 7.11.90
  • CMake v3.7 (from cmake website)

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)?
sehe
  • 374,641
  • 47
  • 450
  • 633
ZeroDefect
  • 663
  • 1
  • 8
  • 27

1 Answers1

1
  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

sehe
  • 374,641
  • 47
  • 450
  • 633
  • In relation to point #5 & #6, I was wondering if previous developers had observed these issues with the issues being subsequently fixed. – ZeroDefect Apr 11 '17 at 15:19
  • @ZeroDefect the way to find out is to search the issue tracker and release notes. We can not do that any better than you can. – sehe Apr 11 '17 at 15:27
  • Sorry @sehe, I think a bit of misunderstanding. You asked me why I wanted to install v1.61 and v1.63 on my system. I was trying to justify my decision by pointing out that these issues may have been resolved in subsequent releases. I was not expecting you to search through issue trackers on my behalf :) On a side note, issues often get resolved in code bases without being documented in issue trackers – ZeroDefect Apr 11 '17 at 21:25
  • Note that I gave you the most likely culprit. This is a recurring theme with things that "act global" like logging. (I don't think it's relevant that issues might have been silently fixed. How big is the chance that a random crowd on [SO] is going to have mental "documentation" of it, if maintainers don't even have it? Translate that to the more constructive "I might try a more recent version if I have no other clue". My answer gives you at least 1 constructive clue, and another one in answers 1.-4.) – sehe Apr 13 '17 at 09:38