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?
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.
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.
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.
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.
I have installed libubsan0
and lib64ubsan0
and added -lubsan
option, and my application compiled successfully!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With