2017-04-11 7 views
1

GCC Instrumentation Options 중 일부를 사용하여 런타임 검사에서 C++ 코드의 특정 영역에서 발생하는 문제를 디버그/진단하려고했습니다.gcc에서 fsanitize 스위치를 사용한 부스트와 관련된 문제

문제의 범위를 좁히기 위해 이러한 기능 중 일부를 사용하기 시작했지만 예상치 못한 코드 영역, 즉 Boost 라이브러리에서 오류가 발생했습니다.

gcc 스위치 '-fsanitize = undefined'를 사용하면 gdb가보고하는 런타임 오류가 많이 있음을 알 수 있습니다. 아주 작은 노력으로 이러한 오류를 재현 할 수있는 것 같습니다. 아래에 몇 가지 샘플 코드를 제공했습니다.

환경 구성 :

  • 우분투 v16.10 (Yakkety) x86_x64
  • 부스트 v1.61
  • GCC 6.3.0 (apt-get을 사용) (최근 소스에서 구축하지만, 문제가 발생했습니다 apt-get을에서 버전)
  • GDB 7.11.90
  • (
,536) cmake 웹 사이트에서
  • CMake의 V3.7 CMakefile의 모습

    // $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$              // 
    

    : 다음과 같이

    샘플 코드는

    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의 샘플 출력 : 내가 함께 모여 질문의 수를 있었다

    (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 
    

    내 발견에 대한 생각을 한 후에 :

    1. 이것은 코딩 오류입니까?
    2. 놀랍지 않습니까?
    3. 이러한 오류는 가양 성입니까?
    4. '-fsanitize'스위치를 사용하고 있습니까?
    5. 새로운 버전의 부스트 (예 : v1.63이 소스에서 빌드)를 사용해 볼까요?
    6. v1.61과 v1.63을 모두 내 시스템에 설치할 수는 있습니까 (단 하나의 시스템에만 연결)?
  • 답변

    0
    1. 더 (또는 예,하지만 가능성이 직접적으로 관련)
    2. 네, 왜? 없습니다나는 당신의 대답 (수정 구슬을 사용하여 시간이 아직 실제 코드를보고 지출되지 않음) 아마 여기에서 생각

    을 (also 참조)과 관련 Boost Thread Access Violation in Boost Log on shutdown

    +0

    가 # 5 & # 6 점으로 I 이전 개발자들이이 문제를 계속적으로 해결했는지 궁금해했습니다. – ZeroDefect

    +0

    @ZeroDefect는 문제 추적기와 릴리스 노트를 검색하는 방법을 찾아냅니다. 우리가 할 수있는 것보다 더 잘 할 수는 없습니다. – sehe

    +0

    미안하지만, 나는 약간의 오해를 생각합니다. 내 시스템에 v1.61 및 v1.63을 설치하려는 이유를 묻습니다. 나는이 문제가 후속 릴리스에서 해결되었을 수도 있음을 지적함으로써 내 결정을 정당화하려고 노력했습니다. 나는 당신을 대신하여 이슈 트래커를 통해 검색 할 것을 기대하지는 않았다. 이슈 추적기에 문서화되지 않고 코드베이스에서 이슈가 종종 해결된다. – ZeroDefect