When compiling and testing Gnulib and Gnulib-using programs, certain
compiler options can help improve reliability. First of all, make it
a habit to use ‘-Wall’ in all compilation commands. Beyond that,
the manywarnings module enables several forms of static checking in
GCC and related compilers (see manywarnings).
For dynamic checking, you can run configure with CFLAGS
options appropriate for your compiler. For example:
./configure \ CPPFLAGS='-Wall'\ CFLAGS='-g3 -O2'\ ' -D_FORTIFY_SOURCE=3'\ ' -D_GLIBCXX_ASSERTIONS'\ ' -fsanitize=undefined'\ ' -fsanitize-trap=all'
Here:
-D_FORTIFY_SOURCE=3 and -D_GLIBCXX_ASSERTIONS
enable extra security hardening checks in
the GNU C library and GNU C++ library, respectively.
-fsanitize=undefined enables GCC’s undefined behavior sanitizer
(ubsan), and
-fsanitize-trap=all causes ubsan to
abort the program (through an “illegal instruction” signal). This
measure stops exploit attempts and also allows you to debug the issue.
Without the -fsanitize-trap=all option,
-fsanitize=undefined causes messages to be printed, and
execution continues after an undefined behavior situation.
The message printing causes GCC-like compilers to arrange for the
program to dynamically link to libraries it might not otherwise need.
With GCC, instead of -fsanitize-trap=all you can
use the -static-libubsan option to arrange for two of the extra
libraries (libstdc++ and libubsan) to be linked
statically rather than dynamically, though this typically bloats the
executable and the remaining extra libraries are still linked
dynamically.
It is also good to occasionally run the programs under valgrind
(see Running self-tests under valgrind).
GCC’s -fhardened option can also be used, but with caution
because it is designed for production more than testing, and therefore
enables -ftrivial-auto-var-init=zero which can mask program
errors.