首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ASAN检测与动态加载库共享的类的vtable的ODR冲突。

ASAN检测与动态加载库共享的类的vtable的ODR冲突。
EN

Stack Overflow用户
提问于 2019-08-07 08:58:33
回答 1查看 2.9K关注 0票数 4

我正在做一个项目,它有一个包含日志、断言处理等内容的"util“库,它被编译成一个静态库,并添加了-fPIC。我还有一个插件系统,其中插件是通过dlopen在运行时加载的共享库。这些插件和主可执行文件都使用静态util库。

问题是:现在我在使用ASAN时得到了AddressSanitizer: odr-violation错误。size=40 'vtable for StdStreamWriter'两次报告了这个问题,其中StdStreamWriter是静态库内部使用的接口的实现。

我非常努力地在MWE中复制这一结果:

  • 创建一个公开某些函数的静态库
  • 在其中使用std::shared_ptr中的接口和实现
  • 根据此创建一个共享库。
  • 创建针对静态库和共享库dlopen的可执行文件链接

CMakeLists.txt

代码语言:javascript
复制
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中的不同结果

  • MWE (无ODR错误)显示V vtable for Impl
  • 针灸程序显示D vtable for StdStreamWriter

我想这个错误来自于DV之间的差异,这导致vtables没有被合并。

这种差异是从何而来的?什么时候决定的?我将共享库的链接命令简化为“基本要素”(clang++-8 -shared -fsanitize=address,undefined -o <..> <all *.o and *.so>),但仍然得到了D vtable而不是V vtable

我还能做什么来解决这个问题?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-25 16:32:26

这很可能是由Clang的Asan实现中的已知问题引起的,这导致它用模糊链接 (通常是类vtable或typeinfos)检测静态数据的错误ODR违规行为。

作为一种解决办法,尝试使用-mllvm -asan-use-private-alias=1进行编译,并在运行代码之前执行export ASAN_OPTIONS=use_odr_indicator=1

如果这解决了你的问题,请在上述问题上发表评论,以增加在上游一劳永逸地解决问题的机会。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57390595

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档