Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using GCC Undefined Behavior Sanitizer

Today I have read an article about GCC Undefined Behavior Sanitizer (ubsan). However, when I follow steps there (add -fsanitize=undefined to my code), the compiler (GCC 4.9.2 on Ubuntu 15.04) says that some references are not defined:

||=== 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_overflow'|
obj/Debug/App.o||In function `std::_Vector_base<unsigned long long, std::allocator<unsigned long long> >::~_Vector_base()':|
/usr/include/c++/4.9/bits/stl_vector.h|161|undefined reference to `__ubsan_handle_sub_overflow'|
...
||More errors follow but not being shown.|
||Edit the max errors limit in compiler options...|
||=== Build failed: 50 error(s), 0 warning(s) (0 minute(s), 23 second(s)) ===|

How can I fix this?

like image 451
Ilya Avatar asked Aug 04 '15 07:08

Ilya


People also ask

How does ubsan work?

UBSAN is a runtime undefined behaviour checker. UBSAN uses compile-time instrumentation to catch undefined behavior (UB). Compiler inserts code that perform certain kinds of checks before operations that may cause UB. If check fails (i.e. UB detected) __ubsan_handle_* function called to print error message.

What is ubsan?

UndefinedBehaviorSanitizer (UBSan) is a fast undefined behavior detector. UBSan modifies the program at compile-time to catch various kinds of undefined behavior during program execution, for example: Array subscript out of bounds, where the bounds can be statically determined.

How do you check for undefined behavior in C++?

However, it is possible to determine whether a specific execution of a C++ produced undefined behavior. One way to do this would be to make a C++ interpreter that steps through the code according to the definitions set out in the spec, at each point determining whether or not the code has undefined behavior.

What does GCC Fsanitize do?

This option disables all previously enabled sanitizers. -fsanitize=all is not allowed, as some sanitizers cannot be used together. This option forces GCC to use custom shadow offset in AddressSanitizer checks. It is useful for experimenting with different shadow memory layouts in Kernel AddressSanitizer.


2 Answers

I have installed libubsan0 and lib64ubsan0 and added -lubsan option, and my application compiled successfully!

like image 120
Ilya Avatar answered Oct 19 '22 03:10

Ilya


The very same article you cited, as seen at its new home, already provides the answer, but you didn't notice it... bold mine:

GCC recently (version 4.9) gained Undefined Behavior Sanitizer (ubsan), a run-time checker for the C and C++ languages. In order to check your program with ubsan, compile and link the program with -fsanitize=undefined option.

I think the correct way to solve this is not to manually link with ubsan, but instead to simply also pass -fsanitize=undefined to the linker, not just the compiler. Sure, reinventing the wheel might work for you, but it's not needed, and there might be a reason that there is a specific linker flag for this, instead.

Certainly, that works: I was suddenly getting piles of undefined reference errors and, after giving up and just not using it for months, yugr's answer here pointed me in the right direction: I was only passing -fsanitize=undefined to meson.add_project_arguments(), but those only go to the compiler; I also needed to pass it to meson.add_project_link_arguments(). After adding that, the errors are gone, and the program links.

like image 19
underscore_d Avatar answered Oct 19 '22 03:10

underscore_d