build: add options to compile with address/undefined sanitizers

This adds two new options to the configure scripts to compile NM,
clients and libraries with the address and undefined-behavior
sanitizers available in recent GCC versions. Clang is not supported at
moment.
This commit is contained in:
Beniamino Galvani 2016-04-04 21:30:43 +02:00
parent b5efd22c14
commit 01540cf1d3
5 changed files with 60 additions and 4 deletions

View File

@ -972,6 +972,39 @@ if (test "${enable_ld_gc}" != "no"); then
fi
fi
AC_ARG_ENABLE(address-sanitizer, AS_HELP_STRING([--enable-address-sanitizer],
[Compile with address sanitizer (default: no)]))
if (test "${enable_address_sanitizer}" = "yes"); then
CC_CHECK_FLAGS_APPEND([asan_cflags], [CFLAGS], [-fsanitize=address])
AS_IF([test -z "$asan_cflags"],
[AC_MSG_ERROR([*** -fsanitize=address is not supported])])
sanitizer_cflags="$sanitizer_cflags -fsanitize=address"
sanitizer_ldflags="$sanitizer_ldflags -Wc,-fsanitize=address"
sanitizers="${sanitizers}asan "
fi
AC_ARG_ENABLE(undefined-sanitizer, AS_HELP_STRING([--enable-undefined-sanitizer],
[Compile with undefined behavior sanitizer (default: no)]))
if (test "${enable_undefined_sanitizer}" = "yes"); then
CC_CHECK_FLAGS_APPEND([ubsan_cflags], [CFLAGS], [-fsanitize=undefined])
AS_IF([test -z "$ubsan_cflags"],
[AC_MSG_ERROR([*** -fsanitize=undefined is not supported])])
sanitizer_cflags="$sanitizer_cflags -fsanitize=undefined"
sanitizer_ldflags="$sanitizer_ldflags -Wc,-fsanitize=undefined"
sanitizers="${sanitizers}ubsan "
fi
if test -n "$sanitizers"; then
CFLAGS="$CFLAGS $sanitizer_cflags -DVALGRIND=1 -fno-omit-frame-pointer"
LDFLAGS="$LDFLAGS $sanitizer_ldflags"
sanitizers="${sanitizers% }"
AC_SUBST(SANITIZER_ENV, [ASAN_OPTIONS=detect_leaks=0])
fi
AC_SUBST(SANITIZERS, [$sanitizers])
dnl -------------------------
dnl Vala bindings
dnl -------------------------
@ -1068,7 +1101,6 @@ fi
AM_CONDITIONAL(BUILD_SETTING_DOCS, test "$build_setting_docs" = "yes")
AM_CONDITIONAL(SETTING_DOCS_AVAILABLE, test "$build_setting_docs" = "yes" -o "$have_setting_docs" = "yes")
AC_CONFIG_FILES([
Makefile
shared/Makefile
@ -1233,4 +1265,5 @@ echo " code coverage: $enable_code_coverage"
echo " LTO: $enable_lto"
echo " linker garbage collection: $enable_ld_gc"
echo " JSON validation: $enable_json_validation"
echo " sanitizers: $sanitizers"
echo

View File

@ -375,6 +375,8 @@ intltoolize --automake --copy --force
%if %{with debug}
--with-more-logging \
--with-more-asserts=10000 \
--enable-address-sanitizer \
--enable-undefined-sanitizer \
%endif
--enable-ppp=yes \
--with-libaudit=yes-disabled-by-default \

View File

@ -196,6 +196,10 @@ CLEANFILES = $(BUILT_SOURCES)
INTROSPECTION_GIRS =
INTROSPECTION_COMPILER_ARGS = --includedir=$(top_builddir)/libnm-util
# Pass SANITIZER_ENV where a command that uses built libraries is
# executed, to suppress possible errors
INTROSPECTION_SCANNER_ENV = $(SANITIZER_ENV)
if HAVE_INTROSPECTION
introspection_sources = $(libnminclude_HEADERS) $(libnm_glib_la_csources)

View File

@ -169,6 +169,10 @@ INTROSPECTION_GIRS =
INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir)
INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir)
# Pass SANITIZER_ENV where a command that uses built libraries is
# executed, to suppress possible errors
INTROSPECTION_SCANNER_ENV = $(SANITIZER_ENV)
if HAVE_INTROSPECTION
introspection_sources = $(libnm_util_include_HEADERS) $(nodist_libnm_util_include_HEADERS) $(libnm_util_la_csources)

View File

@ -141,12 +141,10 @@ libnm_la_LIBADD = \
$(UUID_LIBS) \
$(GUDEV_LIBS)
libnm_la_LDFLAGS = \
$(CODE_COVERAGE_LDFLAGS)
SYMBOL_VIS_FILE=$(srcdir)/libnm.ver
libnm_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \
$(CODE_COVERAGE_LDFLAGS) \
-version-info "1:0:1"
###
@ -170,6 +168,10 @@ INTROSPECTION_COMPILER_ARGS = \
--includedir=$(top_srcdir)/libnm \
--includedir=$(top_builddir)/libnm
# Pass SANITIZER_ENV where a command that uses built libraries is
# executed, to suppress possible errors
INTROSPECTION_SCANNER_ENV = $(SANITIZER_ENV)
if HAVE_INTROSPECTION
introspection_sources = \
$(libnm_core_headers) \
@ -213,9 +215,16 @@ docs_sources = $(filter-out %/nm-core-enum-types.c,$(libnm_core_sources))
nm-setting-docs-overrides.xml: generate-plugin-docs.pl $(docs_sources)
$(srcdir)/generate-plugin-docs.pl dbus $(top_srcdir)/libnm-core $@
# When the python scripts loads libnm and the address sanitizers is
# enabled, we must LD_PRELOAD libasan otherwise it will complain that
# it was not loaded as initial library.
nm-property-docs.xml: generate-setting-docs.py $(docs_sources) | NM-1.0.gir NM-1.0.typelib libnm.la
export GI_TYPELIB_PATH=$(abs_builddir)$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH}; \
export LD_LIBRARY_PATH=$(abs_builddir)/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}; \
if echo $(CFLAGS) | grep -e -fsanitize=address; then \
export LD_PRELOAD="$${LD_PRELOAD} $$(ldd $(abs_builddir)/.libs/libnm.so | grep libasan\.so\.. -o | head -n 1)"; \
fi; \
[ -n "$(SANITIZER_ENV)" ] && export $(SANITIZER_ENV) ; \
$(srcdir)/generate-setting-docs.py \
--gir $(builddir)/NM-1.0.gir \
--output $@
@ -223,6 +232,10 @@ nm-property-docs.xml: generate-setting-docs.py $(docs_sources) | NM-1.0.gir NM-1
nm-setting-docs.xml: generate-setting-docs.py $(docs_sources) nm-setting-docs-overrides.xml | NM-1.0.gir NM-1.0.typelib libnm.la
export GI_TYPELIB_PATH=$(abs_builddir)$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH}; \
export LD_LIBRARY_PATH=$(abs_builddir)/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}; \
if echo $(CFLAGS) | grep -e -fsanitize=address; then \
export LD_PRELOAD="$${LD_PRELOAD} $$(ldd $(abs_builddir)/.libs/libnm.so | grep libasan\.so\.. -o | head -n 1)"; \
fi; \
[ -n "$(SANITIZER_ENV)" ] && export $(SANITIZER_ENV) ; \
$(srcdir)/generate-setting-docs.py \
--gir $(builddir)/NM-1.0.gir \
--overrides $(builddir)/nm-setting-docs-overrides.xml \