Skip to content

Commit

Permalink
Add AddressSanitizer (-fsanitize=address) option. (#669)
Browse files Browse the repository at this point in the history
Details:
- Added support for AddressSanitizer (ASan), a compiler-integrated 
  memory error detector. The option (disabled by default) enables 
  compiling and linking with the -fsanitize=address flag supported by 
  clang, gcc, and probably others. This flag is employed during 
  compilation of all BLIS source files *except* for optimized kernels, 
  which are exempted because ASan usually requires an extra register,
  which violates the constraints for many gemm microkernels.
- Minor whitespace, comment, ordering, and configure help text updates.
  • Loading branch information
devinamatthews authored Sep 29, 2022
1 parent b861c71 commit 42d0e66
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 23 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,7 @@ showconfig: check-env
@echo "install includedir: $(INSTALL_INCDIR)"
@echo "install sharedir: $(INSTALL_SHAREDIR)"
@echo "debugging status: $(DEBUG_TYPE)"
@echo "enable AddressSanitizer? $(MK_ENABLE_ASAN)"
@echo "enabled threading model(s): $(THREADING_MODEL)"
@echo "enable BLAS API? $(MK_ENABLE_BLAS)"
@echo "enable CBLAS API? $(MK_ENABLE_CBLAS)"
Expand Down
3 changes: 3 additions & 0 deletions build/config.mk.in
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ LDFLAGS_PRESET := @ldflags_preset@
# The level of debugging info to generate.
DEBUG_TYPE := @debug_type@

# Whether to compile and link the AddressSanitizer library.
MK_ENABLE_ASAN := @enable_asan@

# Whether operating system support was requested via --enable-system.
ENABLE_SYSTEM := @enable_system@

Expand Down
34 changes: 27 additions & 7 deletions common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ get-noopt-cxxflags-for = $(strip $(CFLAGS_PRESET) \
get-refinit-cflags-for = $(strip $(call load-var-for,COPTFLAGS,$(1)) \
$(call get-noopt-cflags-for,$(1)) \
-DBLIS_CNAME=$(1) \
$(BUILD_ASANFLAGS) \
$(BUILD_CPPFLAGS) \
$(BUILD_SYMFLAGS) \
-DBLIS_IN_REF_KERNEL=1 \
Expand All @@ -129,6 +130,7 @@ get-refkern-cflags-for = $(strip $(call load-var-for,CROPTFLAGS,$(1)) \
$(call get-noopt-cflags-for,$(1)) \
$(COMPSIMDFLAGS) \
-DBLIS_CNAME=$(1) \
$(BUILD_ASANFLAGS) \
$(BUILD_CPPFLAGS) \
$(BUILD_SYMFLAGS) \
-DBLIS_IN_REF_KERNEL=1 \
Expand All @@ -137,12 +139,14 @@ get-refkern-cflags-for = $(strip $(call load-var-for,CROPTFLAGS,$(1)) \

get-config-cflags-for = $(strip $(call load-var-for,COPTFLAGS,$(1)) \
$(call get-noopt-cflags-for,$(1)) \
$(BUILD_ASANFLAGS) \
$(BUILD_CPPFLAGS) \
$(BUILD_SYMFLAGS) \
)

get-frame-cflags-for = $(strip $(call load-var-for,COPTFLAGS,$(1)) \
$(call get-noopt-cflags-for,$(1)) \
$(BUILD_ASANFLAGS) \
$(BUILD_CPPFLAGS) \
$(BUILD_SYMFLAGS) \
)
Expand Down Expand Up @@ -201,11 +205,14 @@ get-sandbox-cxxflags-for = $(strip $(call load-var-for,COPTFLAGS,$(1)) \
# Define a separate function that will return appropriate flags for use by
# applications that want to use the same basic flags as those used when BLIS
# was compiled. (NOTE: This is the same as the $(get-frame-cflags-for ...)
# function, except that it omits two variables that contain flags exclusively
# for use when BLIS is being compiled/built: BUILD_CPPFLAGS, which contains a
# cpp macro that confirms that BLIS is being built; and BUILD_SYMFLAGS, which
# contains symbol export flags that are only needed when a shared library is
# being compiled/linked.)
# function, except that it omits a few variables that contain flags exclusively
# for use when BLIS is being compiled/built:
# - BUILD_CPPFLAGS, which contains a cpp macro that confirms that BLIS
# is being built;
# - BUILD_SYMFLAGS, which contains symbol export flags that are only
# needed when a shared library is being compiled/linked; and
# - BUILD_ASANFLAGS, which contains a flag that causes the compiler to
# insert instrumentation for memory error detection.
get-user-cflags-for = $(strip $(call load-var-for,COPTFLAGS,$(1)) \
$(call get-noopt-cflags-for,$(1)) \
)
Expand Down Expand Up @@ -563,6 +570,11 @@ ifeq ($(DEBUG_TYPE),sde)
LDFLAGS := $(filter-out $(LIBMEMKIND),$(LDFLAGS))
endif

# If AddressSanitizer is enabled, add the compiler flag to LDFLAGS.
ifeq ($(MK_ENABLE_ASAN),yes)
LDFLAGS += -fsanitize=address
endif

# Specify the shared library's 'soname' field.
# NOTE: The flag for creating shared objects is different for Linux and OS X.
ifeq ($(OS_NAME),Darwin)
Expand Down Expand Up @@ -796,11 +808,19 @@ $(foreach c, $(CONFIG_LIST_FAM), $(eval $(call append-var-for,CXXLANGFLAGS,$(c))
CPPROCFLAGS := -D_POSIX_C_SOURCE=200112L
$(foreach c, $(CONFIG_LIST_FAM), $(eval $(call append-var-for,CPPROCFLAGS,$(c))))

# --- AddressSanitizer flags ---

ifeq ($(MK_ENABLE_ASAN),yes)
BUILD_ASANFLAGS := -fsanitize=address
else
BUILD_ASANFLAGS :=
endif

# --- Threading flags ---

# NOTE: We don't have to explicitly omit -pthread when --disable-system is given
# since that option forces --enable-threading=none, and thus -pthread never gets
# added to begin with.
# since that option forces --enable-threading=single, and thus -pthread never
# gets added to begin with.

CTHREADFLAGS :=

Expand Down
61 changes: 45 additions & 16 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,22 @@ print_usage()
echo " "
echo " --enable-mem-tracing, --disable-mem-tracing"
echo " "
echo " Enable (disable by default) output to stdout that traces"
echo " Enable (disabled by default) output to stdout that traces"
echo " the allocation and freeing of memory, including the names"
echo " of the functions that triggered the allocation/freeing."
echo " Enabling this option WILL NEGATIVELY IMPACT PERFORMANCE."
echo " Please use only for informational/debugging purposes."
echo " "
echo " --enable-asan, --disable-asan"
echo " "
echo " Enable (disabled by default) compiling and linking BLIS"
echo " framework code with the AddressSanitizer (ASan) library."
echo " Optimized kernels are NOT compiled with ASan support due"
echo " to limitations of register assignment in inline assembly."
echo " WARNING: ENABLING THIS OPTION WILL NEGATIVELY IMPACT"
echo " PERFORMANCE. Please use only for informational/debugging"
echo " purposes."
echo " "
echo " -i SIZE, --int-size=SIZE"
echo " "
echo " Set the size (in bits) of internal BLIS integers and"
Expand Down Expand Up @@ -2451,6 +2461,9 @@ main()
debug_type=''
debug_flag=''

# A flag indicating whether AddressSanitizer should be used.
enable_asan='no'

# The system flag.
enable_system='yes'

Expand Down Expand Up @@ -2576,6 +2589,12 @@ main()
disable-debug)
debug_flag=0
;;
enable-asan)
enable_asan='yes'
;;
disable-asan)
enable_asan='no'
;;
enable-verbose-make)
enable_verbose='yes'
;;
Expand Down Expand Up @@ -3357,6 +3376,20 @@ main()
echo "${script_name}: no preset LDFLAGS detected."
fi

# Check if the verbose make flag was specified.
if [ "x${enable_verbose}" = "xyes" ]; then
echo "${script_name}: enabling verbose make output. (disable with 'make V=0'.)"
else
echo "${script_name}: disabling verbose make output. (enable with 'make V=1'.)"
fi

# Check if the ARG_MAX hack was requested.
if [ "x${enable_arg_max_hack}" = "xyes" ]; then
echo "${script_name}: enabling ARG_MAX hack."
else
echo "${script_name}: disabling ARG_MAX hack."
fi

# Check if the debug flag was specified.
if [ -n "${debug_flag}" ]; then
if [ "x${debug_type}" = "xopt" ]; then
Expand All @@ -3373,29 +3406,24 @@ main()
echo "${script_name}: debug symbols disabled."
fi

# Check if the verbose make flag was specified.
if [ "x${enable_verbose}" = "xyes" ]; then
echo "${script_name}: enabling verbose make output. (disable with 'make V=0'.)"
# Check if the AddressSanitizer flag was specified.
if [ "x${enable_asan}" = "xyes" ]; then
echo "${script_name}: enabling AddressSanitizer support (except for optimized kernels)."
else
echo "${script_name}: disabling verbose make output. (enable with 'make V=1'.)"
enable_asan='no'
echo "${script_name}: AddressSanitizer support disabled."
fi

# Check if the ARG_MAX hack was requested.
if [ "x${enable_arg_max_hack}" = "xyes" ]; then
echo "${script_name}: enabling ARG_MAX hack."
else
echo "${script_name}: disabling ARG_MAX hack."
fi

enable_shared_01=1
# Check if the static lib flag was specified.
if [ "x${enable_static}" = "xyes" -a "x${enable_shared}" = "xyes" ]; then
echo "${script_name}: building BLIS as both static and shared libraries."
enable_shared_01=1
elif [ "x${enable_static}" = "xno" -a "x${enable_shared}" = "xyes" ]; then
echo "${script_name}: building BLIS as a shared library (static library disabled)."
enable_shared_01=1
elif [ "x${enable_static}" = "xyes" -a "x${enable_shared}" = "xno" ]; then
echo "${script_name}: building BLIS as a static library (shared library disabled)."
enable_shared_01=0
elif [ "x${enable_static}" = "xno" -a "x${enable_shared}" = "xyes" ]; then
echo "${script_name}: building BLIS as a shared library (static library disabled)."
else
echo "${script_name}: Both static and shared libraries were disabled."
echo "${script_name}: *** Please enable one (or both) to continue."
Expand Down Expand Up @@ -3917,7 +3945,7 @@ main()
# Create a #define for the configuration family (config_name).
uconf=$(echo ${config_name} | tr '[:lower:]' '[:upper:]')
config_name_define="#define BLIS_FAMILY_${uconf}\n"

# Create a list of #defines, one for each configuration in config_list.
config_list_defines=""
for conf in ${config_list}; do
Expand Down Expand Up @@ -4012,6 +4040,7 @@ main()
| sed -e "s/@libpthread@/${libpthread_esc}/g" \
| sed -e "s/@cflags_preset@/${cflags_preset_esc}/g" \
| sed -e "s/@ldflags_preset@/${ldflags_preset_esc}/g" \
| sed -e "s/@enable_asan@/${enable_asan}/g" \
| sed -e "s/@debug_type@/${debug_type}/g" \
| sed -e "s/@enable_system@/${enable_system}/g" \
| sed -e "s/@threading_model@/${threading_model}/g" \
Expand Down

0 comments on commit 42d0e66

Please sign in to comment.