我正在做一个项目,它有一个包含日志、断言处理等内容的"util“库,它被编译成一个静态库,并添加了-fPIC。我还有一个插件系统,其中插件是通过dlopen在运行时加载的共享库。这些插件和主可执行文件都使用静态util库。
问题是:现在我在使用ASAN时得到了AddressSanitizer: odr-violation错误。size=40 'vtable for StdStreamWriter'两次报告了这个问题,其中StdStreamWriter是静态库内部使用的接口的实现。
我非常努力地在MWE中复制这一结果:
dlopen的可执行文件链接CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(proj)
set(sanitizer_flags "-fsanitize=address,undefined -fno-omit-frame-pointer")
string(APPEND CMAKE_CXX_FLAGS " ${sanitizer_flags}")
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${sanitizer_flags}")
string(APPEND CMAKE_MODULE_LINKER_FLAGS " ${sanitizer_flags}")
add_library(foo STATIC foo.cpp)
target_compile_features(foo PUBLIC cxx_std_14)
set_target_properties(foo PROPERTIES CXX_EXTENSIONS OFF POSITION_INDEPENDENT_CODE ON)
add_library(lib SHARED lib.cpp)
target_link_libraries(lib foo)
add_executable(main main.cpp)
target_link_libraries(main foo dl)然而,无论我如何努力,在MWE中都不会出现这个问题。
我将这种差异归因于nm -C liblib.so | grep vtable中的不同结果
V vtable for ImplD vtable for StdStreamWriter我想这个错误来自于D和V之间的差异,这导致vtables没有被合并。
这种差异是从何而来的?什么时候决定的?我将共享库的链接命令简化为“基本要素”(clang++-8 -shared -fsanitize=address,undefined -o <..> <all *.o and *.so>),但仍然得到了D vtable而不是V vtable。
我还能做什么来解决这个问题?
https://stackoverflow.com/questions/57390595
复制相似问题