From ba0f8a7429231993bf67121abab5782f2d216f8a Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser Date: Wed, 16 Jan 2019 14:45:46 +0100 Subject: [PATCH 1/2] make: add initial ubsan support --- Makefile.include | 3 +++ makefiles/ubsan.inc.mk | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 makefiles/ubsan.inc.mk diff --git a/Makefile.include b/Makefile.include index fc16d2dcac..4ce3bb43c4 100644 --- a/Makefile.include +++ b/Makefile.include @@ -503,6 +503,9 @@ include $(RIOTMAKE)/toolchain/$(TOOLCHAIN).inc.mk # overriding the core ldscripts LINKFLAGS += -L$(RIOTBASE)/core/ldscripts +# include undefined behaviour sanitizer (UBSAN) support +include $(RIOTMAKE)/ubsan.inc.mk + # Tell ccache to pass the original file to the compiler, instead of passing the # preprocessed code. Without this setting, the compilation will fail with # -Wimplicit-fallthrough warnings even when the fall through case is properly diff --git a/makefiles/ubsan.inc.mk b/makefiles/ubsan.inc.mk new file mode 100644 index 0000000000..ff2cdbc980 --- /dev/null +++ b/makefiles/ubsan.inc.mk @@ -0,0 +1,36 @@ +# Copyright (C) 2019 Kaspar Schleiser +# +# This file contains support for UBSan, the undefined behaviour sanitizer +# provided by gcc and clang. +# +# Please see doc/doxygen/src/debugging-aids.md for more info. + +# trap, msg_exit, msg_recover +UBSAN_MODE ?= msg_exit + +CFLAGS_UBSAN = -fsanitize=undefined + +ifeq (gnu,$(TOOLCHAIN)) + ifeq (native,$(BOARD)) + ifneq (,$(filter msg_%,$(UBSAN_MODE))) + LINKFLAGS_UBSAN += -lubsan + ifneq (msg_recover,$(UBSAN_MODE)) + CFLAGS_UBSAN += -fno-sanitize-recover=undefined + endif + else + CFLAGS_UBSAN += -fsanitize-undefined-trap-on-error + endif + else + # on real hardware, there's currently no runtime support. + # so just crash when undefined behaviour is triggered. + CFLAGS_UBSAN += -fsanitize-undefined-trap-on-error + endif +else + # libubsan doesn't link properly when using clang. + # thus when using llvm as toolchain, always generate traps. + CFLAGS_UBSAN += -fsanitize-trap=undefined +endif + +all-ubsan: CFLAGS += $(CFLAGS_UBSAN) +all-ubsan: LINKFLAGS += $(LINKFLAGS_UBSAN) +all-ubsan: all From aaa2a7939d68ac86e2d7cdedc698c63f94147a44 Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser Date: Tue, 15 Feb 2022 21:17:03 +0100 Subject: [PATCH 2/2] doc: introduce debugging-aids.md, start with ubsan --- doc/doxygen/riot.doxyfile | 1 + doc/doxygen/src/debugging-aids.md | 48 +++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 doc/doxygen/src/debugging-aids.md diff --git a/doc/doxygen/riot.doxyfile b/doc/doxygen/riot.doxyfile index 1771dbfb75..dcc2407dcb 100644 --- a/doc/doxygen/riot.doxyfile +++ b/doc/doxygen/riot.doxyfile @@ -770,6 +770,7 @@ INPUT = ../../doc.txt \ src/using-cpp.md \ src/using-rust.md \ src/advanced-build-system-tricks.md \ + src/debugging-aids.md \ src/emulators.md \ src/release-cycle.md \ src/changelog.md \ diff --git a/doc/doxygen/src/debugging-aids.md b/doc/doxygen/src/debugging-aids.md new file mode 100644 index 0000000000..963aa11a4d --- /dev/null +++ b/doc/doxygen/src/debugging-aids.md @@ -0,0 +1,48 @@ +# Debugging Tools {#debugging-tools} + +## Undefined Behavior Sanitizer (ubsan) {#ubsan} + +RIOT contains makefile convenience support for gcc/clang's undefined +behaviour sanitizer. + +### Overview + +Both gcc and clang allow generation on code that does runtime checks for +undefined behavior (UB). + +E.g., the following code might trigger UB for some parameters: + +```C +void test(int foo) { + return (foo << 24); +} +``` + +In this case, the signed shift would be alright unless: + +- it would "push out" all bits to the left, with undefined runtime result. Here, + that happens on architectures with 16-bit integers. +- `foo` is negative, with implementation defined runtime results. + +Using ubsan, these can be caught at runtime. + +There are three modes for ubsan that define what happens when the sanitizer +observed undefined behaviour: + +1. `trap` -> cause a trap +2. `msg_exit` -> print a message and exit +3. `msg_recover` -> print a message and continue + +`trap` is available on all RIOT platforms, whereas `msg_exit` and `msg_recover` +are currently only available on `native` when building with gcc, as they require runtime support in +the form of `libubsan`. + +The default is `trap`, or `msg_exit` if available (currently, on native:gnu only). + + +### How to use + +1. build with `make all-ubsan`. + +2. build with `UBSAN_MODE=[trap|msg_exit|msg_recover] make all-ubsan` to + override the ubsan mode.