11#! /usr/bin/env bash
22set -e
33
4- # Runs Gradle with address sanitizer enabled. Arguments are passed directly to Gradle.
5- # If no arguments are specified runs the test task.
6- # The ASAN detection is known to work with the buildenv-core image or Ubuntu 22.04 with a clang setup.
4+ # Enables running Gradle tasks with JNI libraries built with AddressSanitizer (ASan).
5+ #
6+ # Note: currently only objectbox feature branches build JNI libraries with ASan. If this is used
7+ # with "regularly" built JNI libraries this will run without error, but also NOT detect any issues.
8+ #
9+ # Arguments are passed directly to Gradle. If no arguments are specified runs the 'test' task.
10+ #
11+ # This script supports the following environment variables:
12+ #
13+ # - ASAN_LIB_SO: path to ASan library, if not set tries to detect path
14+ # - ASAN_SYMBOLIZER_PATH: path to llvm-symbolizer, if not set tries to detect path
15+ # - ASAN_OPTIONS: ASan options, if not set configures to not detect leaks
16+ #
17+ # The ASan detection is known to work with the buildenv-core:2024-07-11 image or Ubuntu 24.04 with a clang setup.
718
8- # ASAN shared library (gcc or clang setup)
19+ # AddressSanitizer shared library (clang or gcc setup)
20+ # https://github.com/google/sanitizers/wiki/AddressSanitizer
921if [ -z " $ASAN_LIB_SO " ]; then # If not supplied (e.g. by CI script), try to locate the lib:
1022 ASAN_ARCH=$( uname -m) # x86_64 or aarch64
1123 echo " No ASAN_LIB_SO defined, trying to locate dynamically..."
12- # Approach via https://stackoverflow.com/a/54386573/551269
13- ASAN_LIB_SO_GCC=$( gcc -print-file-name=libasan.so || true)
14- ASAN_LIB_SO_CLANG=$( clang -print-file-name=libclang_rt.asan-${ASAN_ARCH} .so || true)
15- # Find in the typical llvm directory (using `tail` for latest version; `head` would be oldest")
24+ # Known to work on Ubuntu 24.04: Find in the typical llvm directory (using `tail` for latest version; `head` would be oldest")
1625 ASAN_LIB_SO_CLANG_LATEST=$( find /usr/lib/llvm-* / -name libclang_rt.asan-${ASAN_ARCH} .so | tail -1)
17- echo " gcc asan lib: ${ASAN_LIB_SO_GCC} "
18- echo " clang asan lib: ${ASAN_LIB_SO_CLANG} "
26+ # Known to work with clang 16 on Rocky Linux 8.10 (path is like /usr/local/lib/clang/16/lib/x86_64-unknown-linux-gnu/libclang_rt.asan.so)
27+ ASAN_LIB_SO_CLANG=$( clang -print-file-name=libclang_rt.asan.so || true)
28+ # Approach via https://stackoverflow.com/a/54386573/551269, but use libasan.so.8 instead of libasan.so
29+ # to not find the linker script, but the actual library (and to avoid parsing it out of the linker script).
30+ ASAN_LIB_SO_GCC=$( gcc -print-file-name=libasan.so.8 || true)
1931 echo " clang latest asan lib: ${ASAN_LIB_SO_CLANG_LATEST} "
20- if [ -f " ${ASAN_LIB_SO_CLANG_LATEST} " ]; then # prefer this so version matches with llvm-symbolizer below
32+ echo " clang asan lib: ${ASAN_LIB_SO_CLANG} "
33+ echo " gcc asan lib: ${ASAN_LIB_SO_GCC} "
34+ # prefer clang version in case clang llvm-symbolizer is used (see below)
35+ if [ -f " ${ASAN_LIB_SO_CLANG_LATEST} " ]; then
2136 export ASAN_LIB_SO=" ${ASAN_LIB_SO_CLANG_LATEST} "
2237 elif [ -f " ${ASAN_LIB_SO_CLANG} " ]; then
2338 export ASAN_LIB_SO=" ${ASAN_LIB_SO_CLANG} "
@@ -29,32 +44,46 @@ if [ -z "$ASAN_LIB_SO" ]; then # If not supplied (e.g. by CI script), try to lo
2944 fi
3045fi
3146
32- # llvm-symbolizer (clang setup only)
47+ # Set up llvm-symbolizer to symbolize a stack trace (clang setup only)
48+ # https://github.com/google/sanitizers/wiki/AddressSanitizerCallStack
3349# Rocky Linux 8 (buildenv-core)
3450if [ -z " $ASAN_SYMBOLIZER_PATH " ]; then
51+ echo " ASAN_SYMBOLIZER_PATH not set, trying to find it in /usr/local/bin/..."
3552 export ASAN_SYMBOLIZER_PATH=" $( find /usr/local/bin/ -name llvm-symbolizer | tail -1 ) "
3653fi
3754# Ubuntu 22.04
3855if [ -z " $ASAN_SYMBOLIZER_PATH " ]; then
56+ echo " ASAN_SYMBOLIZER_PATH not set, trying to find it in /usr/lib/llvm-*/..."
3957 export ASAN_SYMBOLIZER_PATH=" $( find /usr/lib/llvm-* / -name llvm-symbolizer | tail -1) "
4058fi
4159
60+ # Turn off leak detection by default
61+ # https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer
4262if [ -z " $ASAN_OPTIONS " ]; then
63+ echo " ASAN_OPTIONS not set, setting default values"
4364 export ASAN_OPTIONS=" detect_leaks=0"
4465fi
4566
67+ echo " "
68+ echo " ℹ️ test-with-asan.sh final values:"
4669echo " ASAN_LIB_SO: $ASAN_LIB_SO "
4770echo " ASAN_SYMBOLIZER_PATH: $ASAN_SYMBOLIZER_PATH "
4871echo " ASAN_OPTIONS: $ASAN_OPTIONS "
72+ echo " ASAN_LIB_SO resolves to:"
4973ls -l $ASAN_LIB_SO
50- ls -l $ASAN_SYMBOLIZER_PATH
74+ echo " ASAN_SYMBOLIZER_PATH resolves to:"
75+ if [ -z " $ASAN_SYMBOLIZER_PATH " ]; then
76+ echo " WARNING: ASAN_SYMBOLIZER_PATH not set, stack traces will not be symbolized"
77+ else
78+ ls -l $ASAN_SYMBOLIZER_PATH
79+ fi
5180
5281if [[ $# -eq 0 ]] ; then
5382 args=test
5483else
5584 args=$@
5685fi
57- echo " Starting Gradle for target(s) \" $args \" ..."
58- pwd
5986
87+ echo " "
88+ echo " ➡️ Running Gradle with arguments \" $args \" in directory $( pwd) ..."
6089LD_PRELOAD=${ASAN_LIB_SO} ./gradlew ${args}
0 commit comments