【发布时间】:2019-12-09 05:04:07
【问题描述】:
我想使用 UBSAN(未定义的行为清洁剂),但发现它完全没有价值,因为它会报告许多误报。
例如一个简单的std::make_shared<int>(42); 足以触发类似警告
地址 0x00000236de70 内的成员访问,该地址不指向“_Sp_counted_base”类型的对象
将此示例简化为 MWE 表明问题在基类和继承方面更为普遍:
例子:
struct Foo{
int f(){ return g(); }
virtual int g() = 0;
};
struct Bar: Foo{
int g(){ return 42; }
};
int main(){
auto f = new Bar();
return f->g();
}
使用-fsanitize=undefined 编译并观看
example.cpp:15:16: 运行时错误:地址 0x000000726e70 上的成员调用不指向“Bar”类型的对象
0x000000726e70:注意:对象的 vptr 无效
见https://godbolt.org/z/0UiVtu。
连这些简单的案件都没有妥善处理?我错过了什么吗?我应该如何正确使用 UBSAN 来检查我的代码? (这需要[几乎]没有误报)
编辑:因为似乎mwe只适用于godbolt,原始代码如下所示:
#include <boost/iostreams/device/mapped_file.hpp>
#include <boost/iostreams/stream.hpp>
using MMStream = boost::iostreams::stream<boost::iostreams::mapped_file_source>;
int main(){
MMStream stream;
stream.open("a.out");
return !stream;
}
使用clang++-8 -fsanitize=undefined -fvisibility=hidden -I /opt/boost_1_64_0/include/ test.cpp /opt/boost_1_64_0/lib/libboost_iostreams.so 编译并运行会导致类似的错误
运行时错误:在地址 0x00000126ef30 上的成员调用未指向“boost::detail::sp_counted_base”类型的对象
【问题讨论】:
-
您使用的是什么编译器和版本? span>
-
您是否在计算机上尝试过,或者仅在godbolt.org上?可以配置Godbolt.org上的系统,使UBSAN失败。 span>
-
这很有趣。我也有ubsan遇到困难,但在我的程序上,只在GCC下。 clang 的消毒剂工作正常我发现很多关于类似主题的讨论,例如:bugs.llvm.org/show_bug.cgi?id=39191
-
我无法重现这个。
-
它发生在所有编译器上,尽管我注意到 MWE 只在 Godbolt 上工作。我使用我的原始代码生成了 MWE,随后将其剥离为仍然在 Godbolt 上产生错误的基本要素,以尝试不同的编译器并供人们使用。似乎那里的行为确实有所不同,所以我附上了原始的 MWE,它与链接一起引导我找到原因。对“升级提升”作为解决方案并不真正满意,但嗯... span>
标签: c++ undefined-behavior ubsan