Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DAOS-16501 build: Add libsanitize #15105

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions ci/unit/required_packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pkgs="argobots \
fuse3-libs \
gotestsum \
hwloc-devel \
libasan \
libipmctl-devel \
libisa-l-devel \
libfabric-devel \
Expand Down
10 changes: 9 additions & 1 deletion site_scons/components/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,15 @@ def define_components(reqs):
abt_build = ['./configure',
'--prefix=$ARGOBOTS_PREFIX',
'CC=gcc',
'--enable-stack-unwind']
'--enable-stack-unwind=yes']
try:
if reqs.get_env('SANITIZERS') != "":
# NOTE the address sanitizer library add some extra info on the stack and thus ULTs
# need a bigger stack
print("Increase argobots default stack size from 16384 to 32768")
abt_build += ['--enable-default-stacksize=32768']
except KeyError:
pass

if reqs.target_type == 'debug':
abt_build.append('--enable-debug=most')
Expand Down
1 change: 1 addition & 0 deletions site_scons/prereq_tools/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ def __init__(self, env, opts):
['gcc', 'covc', 'clang', 'icc'], ignorecase=2))
opts.Add(EnumVariable('WARNING_LEVEL', "Set default warning level", 'error',
['warning', 'warn', 'error'], ignorecase=2))
opts.Add(('SANITIZERS', 'Instrument C code with google sanitizers', None))

opts.Update(self.__env)

Expand Down
42 changes: 41 additions & 1 deletion site_scons/site_tools/compiler_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from SCons.Script import Configure, Exit, GetOption

FRAME_SIZE_MAX = 4096
DESIRED_FLAGS = ['-fstack-usage',
'-Wno-sign-compare',
'-Wno-missing-attributes',
Expand All @@ -14,7 +15,7 @@
'-Wno-unused-command-line-argument',
'-Wmismatched-dealloc',
'-Wfree-nonheap-object',
'-Wframe-larger-than=4096']
f"-Wframe-larger-than={FRAME_SIZE_MAX}"]

# Compiler flags to prevent optimizing out security checks
DESIRED_FLAGS.extend(['-fno-strict-overflow', '-fno-delete-null-pointer-checks', '-fwrapv'])
Expand Down Expand Up @@ -55,6 +56,25 @@ def _base_setup(env):

env.AppendIfSupported(CCFLAGS=DESIRED_FLAGS)

if 'SANITIZERS' in env and env['SANITIZERS'] != "":
for flag in [f"-Wframe-larger-than={FRAME_SIZE_MAX}", '-fomit-frame-pointer']:
if flag in env["CCFLAGS"]:
env["CCFLAGS"].remove(flag)
cc_flags = [f"-Wframe-larger-than={max(8192, FRAME_SIZE_MAX)}",
'-fno-omit-frame-pointer',
'-fno-common']

asan_flags = []
for sanitizer in env['SANITIZERS'].split(','):
asan_flags.append(f"-fsanitize={sanitizer}")

env.AppendIfSupported(CCFLAGS=cc_flags + asan_flags)

for flag in asan_flags:
if flag in env["CCFLAGS"]:
env.AppendUnique(LINKFLAGS=flag)
print(f"Enabling {flag.split('=')[1]} sanitizer for C code")

if '-Wmismatched-dealloc' in env['CCFLAGS']:
env.AppendUnique(CPPDEFINES={'HAVE_DEALLOC': '1'})

Expand Down Expand Up @@ -184,10 +204,30 @@ def _set_fortify_level(env):
Exit(1)


def _check_func(env, func_name):
"""Check if a function is usable"""
denv = env.Clone()
# NOTE Remove sanitizers to not scramble the test output
if 'SANITIZERS' in denv and denv['SANITIZERS'] != "":
for sanitizer in denv['SANITIZERS'].split(','):
flag = f"-fsanitize={sanitizer}"
if flag not in denv["CCFLAGS"]:
continue
denv["CCFLAGS"].remove(flag)
denv["LINKFLAGS"].remove(flag)

config = Configure(denv)
res = config.CheckFunc(func_name)
config.Finish()

return res


def generate(env):
"""Add daos specific method to environment"""
env.AddMethod(_base_setup, 'compiler_setup')
env.AddMethod(_append_if_supported, "AppendIfSupported")
env.AddMethod(_check_func, "CheckFunc")


def exists(_env):
Expand Down
4 changes: 1 addition & 3 deletions src/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,10 @@ def scons():
base_env_mpi.AppendUnique(CPPPATH=[Dir('include')])

if not env.GetOption('clean') and not env.GetOption('help'):
conf = env.Clone().Configure()
# Detect if we have explicit_bzero
if not conf.CheckFunc('explicit_bzero'):
if not env.CheckFunc('explicit_bzero'):
env.Append(CCFLAGS=['-DNEED_EXPLICIT_BZERO'])
base_env.Append(CCFLAGS=['-DNEED_EXPLICIT_BZERO'])
conf.Finish()

for header in HEADERS:
env.Install(os.path.join('$PREFIX', 'include'), os.path.join('include', header))
Expand Down
2 changes: 1 addition & 1 deletion src/client/dfs/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def configure_lustre(denv):
_print("No installed Lustre version detected")
else:
_print("Installed Lustre version detected")
if not conf.CheckFunc('llapi_unlink_foreign'):
if not denv.CheckFunc('llapi_unlink_foreign'):
_print("Lustre version is not compatible")
else:
_print("Lustre version is compatible")
Expand Down
2 changes: 2 additions & 0 deletions src/control/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ def get_build_flags(benv):
"""Return string of build flags"""
if is_release_build(benv):
return '-buildmode=pie'
if 'SANITIZERS' in benv and benv['SANITIZERS'] != "":
return '-asan'
# enable race detector for non-release builds
return '-race'

Expand Down
2 changes: 1 addition & 1 deletion utils/ansible/ftest/templates/daos-launch.sh.j2
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ function cleanup
mountpoint="/mnt/daos$index"
if run ssh $host sudo mountpoint -q "$mountpoint" ; then
info "Cleaning mount points $mountpoint of host $host"
run ssh $host sudo m -fr $mountpoint/*
run ssh $host sudo rm -fr $mountpoint/*
run ssh $host sudo umount $mountpoint
fi
done
Expand Down
19 changes: 11 additions & 8 deletions utils/ansible/ftest/templates/daos-make.sh.j2
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ function check_cmds
function usage
{
cat <<- EOF
usage: daos-make.sh [OPTIONS]
usage: daos-make.sh [OPTIONS] [-- ARGS]

Build and install DAOS for running avocado functional tests

Expand Down Expand Up @@ -169,7 +169,7 @@ do
-v|--verbose) TRACE_LEVEL=$TRACE_LEVEL_VERBOSE ; shift 1 ;;
-D|--debug) TRACE_LEVEL=$TRACE_LEVEL_DEBUG ; set -x ; shift 1 ;;
-q|--quiet) TRACE_LEVEL=$TRACE_LEVEL_QUIET ; shift 1 ;;
--) shift ; break ;;
--) shift 1 ; args=("$@") ; break ;;
*) fatal "unrecognized command line option: $1" ;;
esac
done
Expand Down Expand Up @@ -212,17 +212,20 @@ run $PIP_EXE install --upgrade pip
run $PIP_EXE install -r "$DAOS_SOURCE_DIR/requirements.txt"

SCONS_OPTS="--directory="$DAOS_SOURCE_DIR" --jobs=$JOBS_NB"
if "$FORCE_INSTALL" ; then
SCONS_OPTS+=" --config=force"
fi

if "$DAOS_BUILD_DEPS" ; then
info "Building DAOS dependencies from source tree $DAOS_SOURCE_DIR"
if ! run "$SCONS_EXE" BUILD_TYPE="$DAOS_BUILD_TYPE" BUILD_ROOT="$DAOS_BUILD_DIR" PREFIX="$DAOS_INSTALL_DIR" $SCONS_OPTS --build-deps=only ; then
if ! run "$SCONS_EXE" BUILD_TYPE="$DAOS_BUILD_TYPE" BUILD_ROOT="$DAOS_BUILD_DIR" PREFIX="$DAOS_INSTALL_DIR" "${args[@]}" $SCONS_OPTS --build-deps=only ; then
fatal "DAOS dependencies could not be properly build"
fi
fi

info "Building DAOS from source tree $DAOS_SOURCE_DIR"
# NOTE Dependencies will not be build as 'no' is default value of the --build-deps option
if ! run env MPI_PKG=any "$SCONS_EXE" BUILD_TYPE="$DAOS_BUILD_TYPE" BUILD_ROOT="$DAOS_BUILD_DIR" PREFIX="$DAOS_INSTALL_DIR" $SCONS_OPTS ; then
if ! run env MPI_PKG=any "$SCONS_EXE" BUILD_TYPE="$DAOS_BUILD_TYPE" BUILD_ROOT="$DAOS_BUILD_DIR" PREFIX="$DAOS_INSTALL_DIR" "${args[@]}" $SCONS_OPTS ; then
fatal "DAOS could not be properly build"
fi

Expand Down Expand Up @@ -266,10 +269,10 @@ run $CLUSH_EXE $CLUSH_OPTS -w $CLIENTS_LIST sudo chmod 755 /usr/bin/dfuse
info "Updating dynamic linker configuration"
{% if "daos_clients" in groups and groups["daos_clients"] | length > 0 %}
run $CLUSH_EXE $CLUSH_OPTS -w $SERVERS_LIST -w $CLIENTS_LIST sudo rm -f /etc/ld.so.cache
run $CLUSH_EXE $CLUSH_OPTS -w $SERVERS_LIST -w $CLIENTS_LIST sudo ldconfig
run $CLUSH_EXE $CLUSH_OPTS -w $SERVERS_LIST -w $CLIENTS_LIST sudo ldconfig "$DAOS_INSTALL_DIR/lib64" "$DAOS_INSTALL_DIR/lib64/daos_srv"
{% else %}
run $CLUSH_EXE $CLUSH_OPTS -w $SERVERS_LIST sudo rm -f /etc/ld.so.cache
run $CLUSH_EXE $CLUSH_OPTS -w $SERVERS_LIST sudo ldconfig
run $CLUSH_EXE $CLUSH_OPTS -w $SERVERS_LIST sudo ldconfig "$DAOS_INSTALL_DIR/lib64" "$DAOS_INSTALL_DIR/lib64/daos_srv"
{% endif %}

if [[ ${MPICH_PATH:+x} ]] ; then
Expand Down Expand Up @@ -618,8 +621,8 @@ fi
info "Updating dynamic linker configuration"
{% if "daos_clients" in groups and groups["daos_clients"] | length > 0 %}
run $CLUSH_EXE $CLUSH_OPTS -w $SERVERS_LIST -w $CLIENTS_LIST sudo rm -f /etc/ld.so.cache
run $CLUSH_EXE $CLUSH_OPTS -w $SERVERS_LIST -w $CLIENTS_LIST sudo ldconfig
run $CLUSH_EXE $CLUSH_OPTS -w $SERVERS_LIST -w $CLIENTS_LIST sudo ldconfig "$DAOS_INSTALL_DIR/lib64" "$DAOS_INSTALL_DIR/lib64/daos_srv"
{% else %}
run $CLUSH_EXE $CLUSH_OPTS -w $SERVERS_LIST sudo rm -f /etc/ld.so.cache
run $CLUSH_EXE $CLUSH_OPTS -w $SERVERS_LIST sudo ldconfig
run $CLUSH_EXE $CLUSH_OPTS -w $SERVERS_LIST sudo ldconfig "$DAOS_INSTALL_DIR/lib64" "$DAOS_INSTALL_DIR/lib64/daos_srv"
{% endif %}
1 change: 1 addition & 0 deletions utils/ansible/ftest/vars/Rocky8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ daos_base_deps:
- iproute
- jq
- lbzip2
- libasan
- numactl
- numactl-libs
- numatop
Expand Down
1 change: 1 addition & 0 deletions utils/scripts/install-el8.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ dnf --nodocs install \
java-1.8.0-openjdk \
json-c-devel \
libaio-devel \
libasan \
libcmocka-devel \
libevent-devel \
libiscsi-devel \
Expand Down
1 change: 1 addition & 0 deletions utils/scripts/install-el9.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ dnf --nodocs install \
java-1.8.0-openjdk \
json-c-devel \
libaio-devel \
libasan \
libcmocka-devel \
libevent-devel \
libipmctl-devel \
Expand Down
1 change: 1 addition & 0 deletions utils/scripts/install-leap15.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ dnf --nodocs install \
hwloc-devel \
java-1_8_0-openjdk-devel \
libaio-devel \
libasan8 \
libcmocka-devel \
libcapstone-devel \
libevent-devel \
Expand Down
1 change: 1 addition & 0 deletions utils/scripts/install-ubuntu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ apt-get install \
golang-go \
kmod \
libaio-dev \
libasan8 \
libboost-dev \
libcapstone-dev \
libcmocka-dev \
Expand Down
6 changes: 5 additions & 1 deletion utils/sl/fake_scons/SCons/Script/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Fake scons environment shutting up pylint on SCons files"""
# Copyright 2016-2023 Intel Corporation
# Copyright 2016-2024 Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -338,6 +338,10 @@ def require(self, env, *kw, headers_only=False):
"""Fake require"""
return

def CheckFunc(self, *_args, **_kw):
"""Fake CheckFunc"""
return True


class Variables():
"""Fake variables"""
Expand Down
Loading