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 (
// $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
내 발견에 대한 생각을 한 후에 :
- 이것은 코딩 오류입니까?
- 놀랍지 않습니까?
- 이러한 오류는 가양 성입니까?
- '-fsanitize'스위치를 사용하고 있습니까?
- 새로운 버전의 부스트 (예 : v1.63이 소스에서 빌드)를 사용해 볼까요?
- v1.61과 v1.63을 모두 내 시스템에 설치할 수는 있습니까 (단 하나의 시스템에만 연결)?
가 # 5 & # 6 점으로 I 이전 개발자들이이 문제를 계속적으로 해결했는지 궁금해했습니다. – ZeroDefect
@ZeroDefect는 문제 추적기와 릴리스 노트를 검색하는 방법을 찾아냅니다. 우리가 할 수있는 것보다 더 잘 할 수는 없습니다. – sehe
미안하지만, 나는 약간의 오해를 생각합니다. 내 시스템에 v1.61 및 v1.63을 설치하려는 이유를 묻습니다. 나는이 문제가 후속 릴리스에서 해결되었을 수도 있음을 지적함으로써 내 결정을 정당화하려고 노력했습니다. 나는 당신을 대신하여 이슈 트래커를 통해 검색 할 것을 기대하지는 않았다. 이슈 추적기에 문서화되지 않고 코드베이스에서 이슈가 종종 해결된다. – ZeroDefect