天道酬勤,学无止境

ubsan

由可变参数模板函数调用上的 lambda 包装器引起的 gcc 分段错误(Segmentation fault on gcc caused by lambda wrapper over variadic template function call)

问题 我今天花了好几个小时试图理解为什么这段代码在g++6.2和g++7.0 ,同时在clang++3.9 (和4.0 )上按预期工作。 我将问题简化为一个 85 行的自包含代码片段,它在正常执行时不会出现段错误,但在 UBSAN 下总是报告错误。 通过使用g++7编译,启用优化并将-fsanitize=undefined作为额外标志传递,该问题可在 wandbox 上重现。 这是 UBSAN 报告的内容: prog.cc: In function 'int main()': prog.cc:61:49: warning: 'ns#0' is used uninitialized in this function [-Wuninitialized] ([&] { ([&] { n.execute(ns...); })(); })(); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~ prog.cc:28:10: note: 'ns#0' was declared here auto execute(TNode& n, TNodes&... ns) ^~~~~~~ prog.cc:30:9: runtime error: member call on null pointer of type 'struct node_then' g++声称ns

2021-10-08 19:55:04    分类:技术分享    c++   segmentation-fault   c++14   undefined-behavior   ubsan

由可变参数模板函数调用上的 lambda 包装器引起的 gcc 分段错误(Segmentation fault on gcc caused by lambda wrapper over variadic template function call)

问题 我今天花了好几个小时试图理解为什么这段代码在g++6.2和g++7.0 ,同时在clang++3.9 (和4.0 )上按预期工作。 我将问题简化为一个 85 行的自包含代码片段,它在正常执行时不会出现段错误,但在 UBSAN 下总是报告错误。 通过使用g++7编译,启用优化并将-fsanitize=undefined作为额外标志传递,该问题可在 wandbox 上重现。 这是 UBSAN 报告的内容: prog.cc: In function 'int main()': prog.cc:61:49: warning: 'ns#0' is used uninitialized in this function [-Wuninitialized] ([&] { ([&] { n.execute(ns...); })(); })(); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~ prog.cc:28:10: note: 'ns#0' was declared here auto execute(TNode& n, TNodes&... ns) ^~~~~~~ prog.cc:30:9: runtime error: member call on null pointer of type 'struct node_then' g++声称ns

2021-10-08 19:53:10    分类:技术分享    c++   segmentation-fault   c++14   undefined-behavior   ubsan

如何抑制来自 UBsan 的一些无符号整数溢出错误?(How to suppress some unsigned-integer-overflow errors from UBsan?)

问题 我的大部分-fsanitize=unsigned-integer-overflow错误都是错误,但有时我会按预期明确使用它,这会导致 UBSan 产生误报。 有没有办法关闭特定表达式的 UBSan 无符号整数溢出检查? 编辑以回应 Shafik 评论,这里是一个例子: unsigned a = 0; unsigned b = a - 1; // error: unsigned integer overflow 大多数时候这是一个错误,有时不是。 使用 UBSan 可以找到每次发生的情况,修复错误,但我还没有找到一种方法来消除误报。 编辑 2:要启用检查,需要通过-fsanitize=integer (启用所有整数检查)或fsanitize=unsigned-integer-overflow 。 从下面的评论看来,该检查似乎仅在 clang 中可用,而在 GCC 中尚不可用。 回答1 如果您想将操作包装在一个函数中,您可以使用__attribute__((no_sanitize("integer")))像这样(实时查看): __attribute__((no_sanitize("integer"))) unsigned calc( unsigned a ) { return a - 1 ; } 我通过对 UbSAN 的错误报告/功能请求抑制支持发现了这一点。 除了函数之外

2021-09-29 14:41:26    分类:技术分享    c++   undefined-behavior   ubsan

Call to function (unknown) through pointer to incorrect function type

I have a program that dynamically links against a library. The program passes a function pointer to that library, to execute. But the ubsan (Undefined Behavior Sanitizer) specified that the pointer is on an incorrect function type. And that occurs only if the callback function has a class as parameter if the callback function has a class as parameter, but only forward declared if I specify the compilation flags: -fvisibility=hidden. I use clang to compile my project. Is it a bug in clang undefined behavior sanitizer? The following code is reduced to a simple test case. Check the comments to

2021-07-29 18:36:57    分类:问答    c++   pointers   undefined-behavior   ubsan

C++ UBSAN produces false positives with derived objects

I wanted to use UBSAN (undefined behavior sanitizer) but found it completely worthless as it reports to many false positives. E.g. a simple std::make_shared<int>(42); is enough to trigger warnings like member access within address 0x00000236de70 which does not point to an object of type '_Sp_counted_base' Reducing this example to a MWE shows that the problem is more general with base classes and inheritance: Example: 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(); } Compile with -fsanitize

2021-06-23 01:32:16    分类:问答    c++   undefined-behavior   ubsan

如何打破 gdb 中的 UBSan 报告并继续?(How can I break on UBSan reports in gdb and continue?)

问题 GCC 和 Clang 的最新版本具有未定义行为清理器 (UBSan),它是一个编译标志 ( -fsanitize=undefined ),它添加了运行时检测代码。 出现错误时,会显示如下警告: packet-ber.c:1917:23: 运行时错误:54645397829836991 左移 8 位不能用“long int”类型表示 现在我想调试它并在所述行上获得调试中断。 对于 Address Sanitizer (ASAN), ASAN_OPTIONS=abort_on_error=1会导致可捕获的致命错误。 唯一可用的 UBSan 选项是 UBSAN_OPTIONS=print_stacktrace=1,这会导致报告的调用跟踪转储。 然而,这不允许我检查局部变量然后继续程序。 因此不可能使用-fsanitize-undefined-trap-on-error 。 我应该如何在 UBSan 报告中插入 gdb? 虽然break __sanitizer::SharedPrintfCode似乎有效,但这个名字看起来很内部。 回答1 虽然中断检测函数(如@Mark Plotnick 和@Iwillnotexist Idonotexist 所述)是一种选择,但更好的方法是中断检测后报告这些问题的函数。 这种方法也用于 ASAN,其中会在__asan_report_error上_

2021-06-22 02:57:16    分类:技术分享    c   gdb   sanitizer   address-sanitizer   ubsan

How to suppress some unsigned-integer-overflow errors from UBsan?

Most of my -fsanitize=unsigned-integer-overflow errors are bugs, but sometimes I explicitly use it as intended, which results in UBSan producing false positives. Is there a way to turn UBSan unsigned-integer-overflow check off for a particular expression? EDIT in response to Shafik comment, here is an example: unsigned a = 0; unsigned b = a - 1; // error: unsigned integer overflow Most of the time that is a bug, sometimes it isn't. With UBSan one can find every time that happens, fix the bugs, but I haven't found a way to silence the false positives. EDIT 2: to enable the check one needs to

2021-06-05 22:44:14    分类:问答    c++   undefined-behavior   ubsan

Segmentation fault on gcc caused by lambda wrapper over variadic template function call

I've spent quite a few hours today trying to understand why this code segfaults on g++6.2 and g++7.0, while happily working as intended on clang++3.9 (and 4.0). I reduced the issue to a 85 lines self-contained code snippet, which does not segfault upon normal execution, but always reports an error under UBSAN. The issue is reproducible on wandbox, by compiling with g++7, enabling optimizations and passing -fsanitize=undefined as an extra flag. This is what UBSAN reports: prog.cc: In function 'int main()': prog.cc:61:49: warning: 'ns#0' is used uninitialized in this function [-Wuninitialized] (

2021-06-04 16:25:22    分类:问答    c++   segmentation-fault   c++14   undefined-behavior   ubsan

How can I break on UBSan reports in gdb and continue?

Recent versions of GCC and Clang feature Undefined Behavior Sanitizer (UBSan) which is a compile flag (-fsanitize=undefined) that adds runtime instrumentation code. On errors, a warning such as this one is shown: packet-ber.c:1917:23: runtime error: left shift of 54645397829836991 by 8 places cannot be represented in type 'long int' Now I would like to debug this and get a debug break on said line. For Address Sanitizer (ASAN) there is ASAN_OPTIONS=abort_on_error=1 which results in a fatal error that is catchable. The only UBSan option that seems usable is UBSAN_OPTIONS=print_stacktrace=1

2021-05-16 06:28:00    分类:问答    c   gdb   sanitizer   address-sanitizer   ubsan

使用GCC Undefined Behavior Sanitizer(Using GCC Undefined Behavior Sanitizer)

问题 今天,我读了一篇有关GCC Undefined Behavior Sanitizer(ubsan)的文章。 但是,当我按照此处的步骤操作(向代码中添加-fsanitize=undefined )时,编译器(Ubuntu 15.04上的GCC 4.9.2)表示未定义一些引用: ||=== Build: Debug in Project (compiler: GNU GCC Compiler) ===| obj/Debug/App.o||In function `App::OnInit()':| /home/ilya/Project/App.cpp|31|undefined reference to `__ubsan_handle_type_mismatch'| /home/ilya/Project/App.cpp|31|undefined reference to `__ubsan_handle_load_invalid_value'| ... obj/Debug/App.o||In function `wxObjectEventFunctor::operator()(wxEvtHandler*, wxEvent&)':| /usr/include/wx-3.0/wx/event.h|3757|undefined reference to `__ubsan_handle_add

2021-05-08 11:53:31    分类:技术分享    c++   gcc   undefined-behavior   undefined-reference   ubsan