Tools to help catch use of uninitialized memory?

It is easy to accidentally read from uninitialized memory after using resize! to grow a vector. Is there an equivalent of the memory sanitizer in C or any other tools for catching this when testing?

I never used it before but could give this a shot
Sanitizer support · The Julia Language

When I run the following I get an error.

$ mkdir /tmp/julia
$ SANITIZE_MEMORY=1 contrib/asan/build.sh /tmp/julia/
checking for gcc... /tmp/julia/asan/../toolchain/usr/tools/clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address
checking whether the C compiler works... no
configure: error: in `/tmp/julia/asan/deps/patchelf-0.17.2':
configure: error: C compiler cannot create executables
See `config.log' for more details
make[1]: *** [/home/nathan/github/julia/deps/patchelf.mk:22: patchelf-0.17.2/build-configured] Error 77
make[1]: Leaving directory '/tmp/julia/asan/deps'
make: *** [/home/nathan/github/julia/Makefile:86: julia-deps] Error 2
make: Leaving directory '/tmp/julia/asan'

There’s possibly some relevant info on the failure there.

I tried this again and found a config.log in /tmp/julia/asan/deps/patchelf-0.17.2/

config.log
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by patchelf configure 0.17.2, which was
generated by GNU Autoconf 2.71.  Invocation command line was

  $ /home/nathan/github/julia/deps/srccache/patchelf-0.17.2//configure --prefix=/tmp/julia/asan/usr --build=x86_64-unknown-linux-gnu --libdir=/tmp/julia/asan/usr/lib --bindir=/tmp/julia/asan/usr/tools 'LDFLAGS= -Wl,-rpath,'\''$$ORIGIN'\'' -Wl,-z,origin -Wl,-rpath-link,/tmp/julia/asan/usr/lib -Wl,--enable-new-dtags -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -Wl,--warn-unresolved-symbols -fsanitize=address -shared-libasan' 'F77=gfortran -march=native -mtune=native -m64' 'CC=/tmp/julia/asan/../toolchain/usr/tools/clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address' 'CXX=/tmp/julia/asan/../toolchain/usr/tools/clang++ -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address' LD=ld LDFLAGS= CPPFLAGS= MAKE=make

## --------- ##
## Platform. ##
## --------- ##

hostname = pop-os
uname -m = x86_64
uname -r = 6.9.3-76060903-generic
uname -s = Linux
uname -v = #202405300957~1732141768~22.04~f2697e1 SMP PREEMPT_DYNAMIC Wed N

/usr/bin/uname -p = x86_64
/bin/uname -X     = unknown

/bin/arch              = x86_64
/usr/bin/arch -k       = unknown
/usr/convex/getsysinfo = unknown
/usr/bin/hostinfo      = unknown
/bin/machine           = unknown
/usr/bin/oslevel       = unknown
/bin/universe          = unknown

PATH: /home/nathan/packages/texlive/bin/x86_64-linux/
PATH: /home/nathan/.cargo/bin/
PATH: /home/nathan/.juliaup/bin/
PATH: /home/nathan/.local/bin/
PATH: /home/nathan/bin/
PATH: /usr/local/sbin/
PATH: /usr/local/bin/
PATH: /usr/sbin/
PATH: /usr/bin/
PATH: /sbin/
PATH: /bin/
PATH: /usr/games/
PATH: /usr/local/games/
PATH: /snap/bin/


## ----------- ##
## Core tests. ##
## ----------- ##

configure:2390: looking for aux files: compile missing install-sh
configure:2403:  trying /home/nathan/github/julia/deps/srccache/patchelf-0.17.2/build-aux/
configure:2432:   /home/nathan/github/julia/deps/srccache/patchelf-0.17.2/build-aux/compile found
configure:2432:   /home/nathan/github/julia/deps/srccache/patchelf-0.17.2/build-aux/missing found
configure:2414:   /home/nathan/github/julia/deps/srccache/patchelf-0.17.2/build-aux/install-sh found
configure:2563: checking for a BSD-compatible install
configure:2636: result: /usr/bin/install -c
configure:2647: checking whether build environment is sane
configure:2702: result: yes
configure:2861: checking for a race-free mkdir -p
configure:2905: result: /usr/bin/mkdir -p
configure:2912: checking for gawk
configure:2947: result: no
configure:2912: checking for mawk
configure:2933: found /usr/bin/mawk
configure:2944: result: mawk
configure:2955: checking whether make sets $(MAKE)
configure:2978: result: yes
configure:3008: checking whether make supports nested variables
configure:3026: result: yes
configure:3212: checking for strip
configure:3233: found /usr/bin/strip
configure:3244: result: strip
configure:3315: checking for objdump
configure:3336: found /usr/bin/objdump
configure:3347: result: objdump
configure:3417: checking for objcopy
configure:3438: found /usr/bin/objcopy
configure:3449: result: objcopy
configure:3519: checking for readelf
configure:3540: found /usr/bin/readelf
configure:3551: result: readelf
configure:3587: checking whether make supports the include directive
configure:3602: make -f confmf.GNU && cat confinc.out
make[2]: Entering directory '/tmp/julia/asan/deps/patchelf-0.17.2'
make[2]: Leaving directory '/tmp/julia/asan/deps/patchelf-0.17.2'
this is the am__doit target
configure:3605: $? = 0
configure:3624: result: yes (GNU style)
configure:3700: checking for gcc
configure:3732: result: /tmp/julia/asan/../toolchain/usr/tools/clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address
configure:4085: checking for C compiler version
configure:4094: /tmp/julia/asan/../toolchain/usr/tools/clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address --version >&5
clang version 18.1.7jl (/cache/yggdrasil/downloads/clones/llvm-project.git-5a9787eb535c2edc5dea030cc221c1d60f38c9f42344f410e425ea2139e233aa ed30d043a240d06bb6e010a41086e75713156f4f)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /tmp/julia/asan/../toolchain/usr/tools
configure:4105: $? = 0
configure:4094: /tmp/julia/asan/../toolchain/usr/tools/clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address -v >&5
clang version 18.1.7jl (/cache/yggdrasil/downloads/clones/llvm-project.git-5a9787eb535c2edc5dea030cc221c1d60f38c9f42344f410e425ea2139e233aa ed30d043a240d06bb6e010a41086e75713156f4f)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /tmp/julia/asan/../toolchain/usr/tools
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/11
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/12
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/12
Candidate multilib: .;@m64
Selected multilib: .;@m64
clang: warning: argument unused during compilation: '-fsanitize=memory' [-Wunused-command-line-argument]
... rest of stderr output deleted ...
configure:4105: $? = 0
configure:4094: /tmp/julia/asan/../toolchain/usr/tools/clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address -V >&5
clang: error: argument to '-V' is missing (expected 1 value)
clang: error: no input files
configure:4105: $? = 1
configure:4094: /tmp/julia/asan/../toolchain/usr/tools/clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address -qversion >&5
clang: error: unknown argument '-qversion'; did you mean '--version'?
clang: error: no input files
configure:4105: $? = 1
configure:4094: /tmp/julia/asan/../toolchain/usr/tools/clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address -version >&5
clang: error: unknown argument '-version'; did you mean '--version'?
clang: error: no input files
configure:4105: $? = 1
configure:4125: checking whether the C compiler works
configure:4147: /tmp/julia/asan/../toolchain/usr/tools/clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address    conftest.c  >&5
clang: error: invalid argument '-fsanitize=address' not allowed with '-fsanitize=memory'
configure:4151: $? = 1
configure:4191: result: no
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "patchelf"
| #define PACKAGE_TARNAME "patchelf"
| #define PACKAGE_VERSION "0.17.2"
| #define PACKAGE_STRING "patchelf 0.17.2"
| #define PACKAGE_BUGREPORT ""
| #define PACKAGE_URL ""
| #define PACKAGE "patchelf"
| #define VERSION "0.17.2"
| /* end confdefs.h.  */
| 
| int
| main (void)
| {
| 
|   ;
|   return 0;
| }
configure:4196: error: in `/tmp/julia/asan/deps/patchelf-0.17.2':
configure:4198: error: C compiler cannot create executables
See `config.log' for more details

## ---------------- ##
## Cache variables. ##
## ---------------- ##

ac_cv_env_CCASFLAGS_set=
ac_cv_env_CCASFLAGS_value=
ac_cv_env_CCAS_set=
ac_cv_env_CCAS_value=
ac_cv_env_CCC_set=
ac_cv_env_CCC_value=
ac_cv_env_CC_set=set
ac_cv_env_CC_value='/tmp/julia/asan/../toolchain/usr/tools/clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address'
ac_cv_env_CFLAGS_set=
ac_cv_env_CFLAGS_value=
ac_cv_env_CPPFLAGS_set=set
ac_cv_env_CPPFLAGS_value=
ac_cv_env_CXXFLAGS_set=
ac_cv_env_CXXFLAGS_value=
ac_cv_env_CXX_set=set
ac_cv_env_CXX_value='/tmp/julia/asan/../toolchain/usr/tools/clang++ -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address'
ac_cv_env_LDFLAGS_set=set
ac_cv_env_LDFLAGS_value=
ac_cv_env_LIBS_set=
ac_cv_env_LIBS_value=
ac_cv_env_build_alias_set=set
ac_cv_env_build_alias_value=x86_64-unknown-linux-gnu
ac_cv_env_host_alias_set=
ac_cv_env_host_alias_value=
ac_cv_env_target_alias_set=
ac_cv_env_target_alias_value=
ac_cv_path_install='/usr/bin/install -c'
ac_cv_path_mkdir=/usr/bin/mkdir
ac_cv_prog_AWK=mawk
ac_cv_prog_ac_ct_CC='/tmp/julia/asan/../toolchain/usr/tools/clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address'
ac_cv_prog_ac_ct_OBJCOPY=objcopy
ac_cv_prog_ac_ct_OBJDUMP=objdump
ac_cv_prog_ac_ct_READELF=readelf
ac_cv_prog_ac_ct_STRIP=strip
ac_cv_prog_make_make_set=yes
am_cv_make_support_nested_variables=yes

## ----------------- ##
## Output variables. ##
## ----------------- ##

ACLOCAL='${SHELL} '\''/home/nathan/github/julia/deps/srccache/patchelf-0.17.2/build-aux/missing'\'' aclocal-1.16'
AMDEPBACKSLASH='\'
AMDEP_FALSE='#'
AMDEP_TRUE=''
AMTAR='$${TAR-tar}'
AM_BACKSLASH='\'
AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
AM_DEFAULT_VERBOSITY='1'
AM_V='$(V)'
AUTOCONF='${SHELL} '\''/home/nathan/github/julia/deps/srccache/patchelf-0.17.2/build-aux/missing'\'' autoconf'
AUTOHEADER='${SHELL} '\''/home/nathan/github/julia/deps/srccache/patchelf-0.17.2/build-aux/missing'\'' autoheader'
AUTOMAKE='${SHELL} '\''/home/nathan/github/julia/deps/srccache/patchelf-0.17.2/build-aux/missing'\'' automake-1.16'
AWK='mawk'
CC='/tmp/julia/asan/../toolchain/usr/tools/clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address'
CCAS=''
CCASDEPMODE=''
CCASFLAGS=''
CCDEPMODE=''
CFLAGS=''
CPPFLAGS=''
CSCOPE='cscope'
CTAGS='ctags'
CXX='/tmp/julia/asan/../toolchain/usr/tools/clang++ -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address'
CXXDEPMODE=''
CXXFLAGS=''
CYGPATH_W='echo'
DEFS=''
DEPDIR='.deps'
ECHO_C=''
ECHO_N='-n'
ECHO_T=''
ETAGS='etags'
EXEEXT=''
HAVE_CXX17=''
INSTALL_DATA='${INSTALL} -m 644'
INSTALL_PROGRAM='${INSTALL}'
INSTALL_SCRIPT='${INSTALL}'
INSTALL_STRIP_PROGRAM='$(install_sh) -c -s'
LDFLAGS=''
LIBOBJS=''
LIBS=''
LTLIBOBJS=''
MAKEINFO='${SHELL} '\''/home/nathan/github/julia/deps/srccache/patchelf-0.17.2/build-aux/missing'\'' makeinfo'
MKDIR_P='/usr/bin/mkdir -p'
OBJCOPY='objcopy'
OBJDUMP='objdump'
OBJEXT=''
PACKAGE='patchelf'
PACKAGE_BUGREPORT=''
PACKAGE_NAME='patchelf'
PACKAGE_STRING='patchelf 0.17.2'
PACKAGE_TARNAME='patchelf'
PACKAGE_URL=''
PACKAGE_VERSION='0.17.2'
PATH_SEPARATOR=':'
READELF='readelf'
SET_MAKE=''
SHELL='/bin/bash'
STRIP='strip'
VERSION='0.17.2'
WITH_ASAN_FALSE=''
WITH_ASAN_TRUE=''
WITH_UBSAN_FALSE=''
WITH_UBSAN_TRUE=''
ac_ct_CC='/tmp/julia/asan/../toolchain/usr/tools/clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize=address'
ac_ct_CXX=''
am__EXEEXT_FALSE=''
am__EXEEXT_TRUE=''
am__fastdepCCAS_FALSE=''
am__fastdepCCAS_TRUE=''
am__fastdepCC_FALSE=''
am__fastdepCC_TRUE=''
am__fastdepCXX_FALSE=''
am__fastdepCXX_TRUE=''
am__include='include'
am__isrc=' -I$(srcdir)'
am__leading_dot='.'
am__nodep='_no'
am__quote=''
am__tar='$${TAR-tar} chof - "$$tardir"'
am__untar='$${TAR-tar} xf -'
bindir='/tmp/julia/asan/usr/tools'
build_alias='x86_64-unknown-linux-gnu'
datadir='${datarootdir}'
datarootdir='${prefix}/share'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
dvidir='${docdir}'
exec_prefix='NONE'
host_alias=''
htmldir='${docdir}'
includedir='${prefix}/include'
infodir='${datarootdir}/info'
install_sh='${SHELL} /home/nathan/github/julia/deps/srccache/patchelf-0.17.2/build-aux/install-sh'
libdir='/tmp/julia/asan/usr/lib'
libexecdir='${exec_prefix}/libexec'
localedir='${datarootdir}/locale'
localstatedir='${prefix}/var'
mandir='${datarootdir}/man'
mkdir_p='$(MKDIR_P)'
oldincludedir='/usr/include'
pdfdir='${docdir}'
prefix='/tmp/julia/asan/usr'
program_transform_name='s,x,x,'
psdir='${docdir}'
runstatedir='${localstatedir}/run'
sbindir='${exec_prefix}/sbin'
sharedstatedir='${prefix}/com'
sysconfdir='${prefix}/etc'
target_alias=''

## ----------- ##
## confdefs.h. ##
## ----------- ##

/* confdefs.h */
#define PACKAGE_NAME "patchelf"
#define PACKAGE_TARNAME "patchelf"
#define PACKAGE_VERSION "0.17.2"
#define PACKAGE_STRING "patchelf 0.17.2"
#define PACKAGE_BUGREPORT ""
#define PACKAGE_URL ""
#define PACKAGE "patchelf"
#define VERSION "0.17.2"

configure: exit 77

I made a custom vector type that errors when reading uninitialized memory by storing a BitVector of valid indexes.

struct MemSanVector{T} <: AbstractVector{T}
    data::Vector{T}
    read_valid::BitVector
    MemSanVector{T}() where T = new{T}(Vector{T}(), BitVector())
end
Base.size(x::MemSanVector) = size(x.data)
Base.IndexStyle(::Type{MemSanVector}) = IndexLinear()
function Base.getindex(x::MemSanVector, i::Int)
    x.read_valid[i] || throw(BoundsError(x, i))
    x.data[i]
end
function Base.setindex!(x::MemSanVector, v, i::Int)
    x.data[i] = v
    x.read_valid[i] = true
    x
end
function Base.resize!(x::MemSanVector, n::Integer)
    if n < length(x)
        resize!(x.data, n)
        resize!(x.read_valid, n)
    elseif n > length(x)
        inc = n - length(x)
        resize!(x.data, n)
        append!(x.read_valid, (false for i in 1:inc))
    end
    x
end
julia> a = MemSanVector{Int64}()
0-element MemSanVector{Int64}

julia> resize!(a, 3);

julia> a[1]
ERROR: BoundsError: attempt to access 3-element MemSanVector{Int64} at index [1]
Stacktrace:
 [1] getindex(x::MemSanVector{Int64}, i::Int64)
   @ Main ~/Documents/memsan/memsan.jl:11
 [2] top-level scope
   @ REPL[9]:1

julia> a .= 5;

julia> a[1]
5

These seem like relevant errors:

It seems there are multiple errors with the command line arguments to clang, perhaps the script is outdated :man_shrugging: