Engee documentation

Sanitizer support

In custom Julia builds, you can use https://github.com/google/sanitizers [sanitizers] to more easily identify certain types of errors in the internal Julia code in C/C++.

Address Sanitizer: easy assembly

Based on the extracted Julia source code, you can create a version that supports address cleanup in Julia and LLVM:

$ mkdir /tmp/julia
$ contrib/asan/build.sh /tmp/julia/

The build directory /tmp/julia is selected here, but it can be any directory of your choice. After the build, run the workload that needs to be tested using `/tmp/julia/julia'. All memory errors will be reported.

For more information, including configuration, see the documentation below.

General provisions

Obviously, to use Clang sanitizers, you will need to use Clang (USECLANG=1), but there is another point: most sanitizers require a runtime library provided by the main compiler, however, the instrumented code generated by JIT Julia relies on the functionality of this library. It follows that the LLVM version of the main compiler must match the version of the LLVM library used in Julia.

To solve this problem, you can simply create a special build folder to provide the appropriate toolkit by performing the build with the parameter BUILD_LLVM_CLANG=1. This toolkit can then be referenced from another build folder by specifying the USECLANG=1 parameter when redefining the 'CC` and CXX variables.

When a shared folder opened with RTLD_DEEPBIND is detected, sanitizers give an error (see https://github.com/google/sanitizers/issues/611 [google/sanitizers#611]). Since the library https://github.com/staticfloat/libblastrampoline [libblastrampoline] uses RTLD_DEEPBIND By default. When using the sanitizer, you must set the environment variable LBT_USE_RTLD_DEEPBIND=0.

To use one of the sanitizers, set SANITIZE=1, and then set the appropriate flag for the desired sanitizer.

Additional flags may be required on macOS. In general, it may look like this with the addition of one flag SANITIZE_* or several listed below.

make -C deps USE_BINARYBUILDER_LLVM=0 LLVM_VER=svn stage-llvm

make -C src SANITIZE=1 USECLANG=1 \
    CC=~+/deps/scratch/llvm-svn/build_Release/bin/clang \
    CXX=~+/deps/scratch/llvm-svn/build_Release/bin/clang++ \
    CPPFLAGS="-isysroot $(xcode-select -p)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" \
    CXXFLAGS="-isystem $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1"

This code can also be placed in the Make.user file so that you don’t have to remember it every time.

Address Sanitizer (ASAN)

To detect or debug memory errors, you can use https://clang.llvm.org/docs/AddressSanitizer.html [address Sanitizer (ASAN)] Clang. By compiling with the SANITIZE_ADDRESS=1 parameter, you enable ASAN for the Julia compiler and the code generated by it. In addition, you can specify LLVM_SANITIZE=1 to also sanitize the LLVM library. Keep in mind that these parameters lead to high costs of computing and memory resources. For example, when using ASAN for Julia and LLVM, testall1 runs 8-10 times longer and consumes 20 times more memory (using the parameters described below, these figures can be reduced by 3 and 4 times, respectively).

By default, Julia sets the ASAN flag allow_user_segv_handler=1, which is necessary for the correct delivery of signals. Using the environment flag ASS_OPTIONS, you can set other parameters; in this case, you will have to repeat the previously specified parameter By default. For example, by specifying fast_unwind_on_malloc=0 and malloc_context_size=2, you can reduce memory consumption due to backtracking accuracy. Currently Julia also sets the detect_leaks=0 parameter, however this will be changed in the future.

Example settings

Step 1. Installing the Toolkit

Extract the Git working tree (or create a build directory outside the tree) in $TOOLCHAIN_WORKTREE and create a configuration file `$TOOLCHAIN_WORKTREE/Make.user' with the following contents:

USE_BINARYBUILDER_LLVM=1
BUILD_LLVM_CLANG=1

Run the following commands:

cd $TOOLCHAIN_WORKTREE
make -C deps install-llvm install-clang install-llvm-tools

to install the toolkit binaries in `$TOOLCHAIN_WORKTREE/usr/tools'.

Step 2. Build Julia with ASAN

Extract the Git working tree (or create a build directory outside the tree) in $BUILD_WORKTREE and create a configuration file `$BUILD_WORKTREE/Make.user' with the following contents:

TOOLCHAIN=$(TOOLCHAIN_WORKTREE)/usr/tools

# используем новый набор инструментальных средств
USECLANG=1
override CC=$(TOOLCHAIN)/clang
override CXX=$(TOOLCHAIN)/clang++
export ASAN_SYMBOLIZER_PATH=$(TOOLCHAIN)/llvm-symbolizer

USE_BINARYBUILDER_LLVM=1

override SANITIZE=1
override SANITIZE_ADDRESS=1

# предписываем сборщику мусора использовать обычные операции выделения и освобождения памяти, к которым привязан ASAN
override WITH_GC_DEBUG_ENV=1

# используем по умолчанию отладочную сборку для более точной информации о номерах строк
override JULIA_BUILD_MODE=debug

# сокращаем объем памяти, потребляемый ASAN
export ASAN_OPTIONS=detect_leaks=0:fast_unwind_on_malloc=0:allow_user_segv_handler=1:malloc_context_size=2

JULIA_PRECOMPILE=1

# предписываем libblastrampoline не использовать RTLD_DEEPBIND
export LBT_USE_RTLD_DEEPBIND=0

Run the following commands:

cd $BUILD_WORKTREE
make debug

to build julia-debug with ASAN.

Memory Sanitizer (MSAN)

To detect the use of uninitialized memory, you can use https://clang.llvm.org/docs/MemorySanitizer.html [memory sanitizer (MSAN)] Clang by compiling with the parameter SANITIZE_MEMORY=1.

Flow Sanitizer (TSAN)

To debug data contests and other thread-related issues, you can use https://clang.llvm.org/docs/ThreadSanitizer.html [thread sanitizer (TSAN)] Clang by compiling with the SANITIZE_THREAD=1 parameter.