Enable gcc undefined behavior sanitizer during coverage build #17409
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
gcc's "undefined behavior" sanitizer can catch a range of misbehaviors at runtime that normally go unnoticed. These include integer and pointer operations that are "undefined" per the relevant C specification.
This PR fixes current undefined behavior detected under gcc 12.2.0 (debian stable/bookworm) on an x64 system, then enables it during unix coverage builds.
Testing
I built and ran the unix tests locally, iterating until there were no remaining diagnostics.
I double checked the places I used the
mem*0
alternative functions for "passing the sniff test" (i.e., is it reasonably expected that zero-lengths would occur here, etc)Trade-offs and Alternatives
I believe that the core changes (memcpy0 etc) are implemented so that they avoid code growth except in the coverage build. (but the CI will tell us for sure)
Not all gcc sanitizers can be enabled simultaneously. So, a choice has to be mad (mainly between -fsanitize=undefined and -fsanitize=memory). I chose the undefined checker, but implemented it so that an override of the makefile variable is possible.
-fsanitize=memory is also nearly error free except for micropython/berkeley-db-1.xx#1
I read that a future C specifiction will make e.g.,
memset(NULL, 0, 0)
(setting zero bytes of a NULL pointer) not-undefined-behavior. When this comes to pass, themem*0
macros can possibly be removed.Different gcc versions might be too different in what they affect, as any diagnostics will make
make test
fail due to the unexpected output.Well, except pattern-based tests which might inadvertently skip over output text that comes from the sanitizer, giving false negatives.