diff --git a/.github/workflows/ubsan.yml b/.github/workflows/ubsan.yml new file mode 100644 index 0000000..0795c55 --- /dev/null +++ b/.github/workflows/ubsan.yml @@ -0,0 +1,90 @@ +name: UBSan (UndefinedBehaviorSanitizer) + +# Undefined behavior detection using UndefinedBehaviorSanitizer +# This workflow builds memtier_benchmark with UBSan enabled and runs +# the full test suite to detect undefined behavior issues. + +on: [push, pull_request] + +jobs: + test-with-ubsan: + runs-on: ubuntu-latest + name: Undefined behavior detection (UBSan) + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install build dependencies + run: | + sudo apt-get -qq update + sudo apt-get install -y \ + build-essential \ + autoconf \ + automake \ + pkg-config \ + libevent-dev \ + zlib1g-dev \ + libssl-dev + + - name: Build with UBSan + run: | + autoreconf -ivf + ./configure --enable-ubsan + make -j + + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: '3.10' + architecture: x64 + + - name: Install Python test dependencies + run: pip install -r ./tests/test_requirements.txt + + - name: Install Redis + run: | + curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg + echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list + sudo apt-get -qq update + sudo apt-get install redis + sudo service redis-server stop + + - name: Increase connection limit + run: | + sudo sysctl -w net.ipv4.tcp_fin_timeout=10 + sudo sysctl -w net.ipv4.tcp_tw_reuse=1 + ulimit -n 40960 + + - name: Generate TLS test certificates + run: ./tests/gen-test-certs.sh + + - name: Test OSS TCP with UBSan + timeout-minutes: 10 + run: | + UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./tests/run_tests.sh + + - name: Test OSS TCP TLS with UBSan + timeout-minutes: 10 + run: | + UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 TLS=1 ./tests/run_tests.sh + + - name: Test OSS TCP TLS v1.2 with UBSan + timeout-minutes: 10 + run: | + UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 TLS_PROTOCOLS='TLSv1.2' TLS=1 ./tests/run_tests.sh + + - name: Test OSS TCP TLS v1.3 with UBSan + timeout-minutes: 10 + run: | + UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 TLS_PROTOCOLS='TLSv1.3' TLS=1 ./tests/run_tests.sh + + - name: Test OSS-CLUSTER TCP with UBSan + timeout-minutes: 10 + run: | + UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 OSS_STANDALONE=0 OSS_CLUSTER=1 ./tests/run_tests.sh + + - name: Test OSS-CLUSTER TCP TLS with UBSan + timeout-minutes: 10 + run: | + UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 OSS_STANDALONE=0 OSS_CLUSTER=1 TLS=1 ./tests/run_tests.sh + diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..024e288 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,142 @@ +# Development Guide + +This document provides information for developers working on memtier_benchmark. + +## Building from Source + +### Prerequisites + +The following libraries are required for building: + +* libevent 2.0.10 or newer. +* OpenSSL (unless TLS support is disabled by `./configure --disable-tls`). + +The following tools are required: +* autoconf +* automake +* pkg-config +* GNU make +* GCC C++ compiler + +### CentOS/Red Hat Linux 7 or newer + +Use the following to install prerequisites: +``` +$ sudo yum install autoconf automake make gcc-c++ \ + zlib-devel libmemcached-devel libevent-devel openssl-devel +``` + +### Ubuntu/Debian + +Use the following to install prerequisites: + +``` +$ sudo apt-get install build-essential autoconf automake \ + libevent-dev pkg-config zlib1g-dev libssl-dev +``` + +### macOS + +To build natively on macOS, use Homebrew to install the required dependencies: + +``` +$ brew install autoconf automake libtool libevent pkg-config openssl@3.0 +``` + +When running `./configure`, if it fails to find libssl it may be necessary to +tweak the `PKG_CONFIG_PATH` environment variable: + +``` +PKG_CONFIG_PATH=`brew --prefix openssl@3.0`/lib/pkgconfig ./configure +``` + +### Building and Installing + +After downloading the source tree, use standard autoconf/automake commands: + +``` +$ autoreconf -ivf +$ ./configure +$ make +$ sudo make install +``` + +## Testing + +The project includes a basic set of integration tests. + +### Integration Tests + +Integration tests are based on [RLTest](https://github.com/RedisLabsModules/RLTest), and specific setup parameters can be provided +to configure tests and topologies (OSS standalone and OSS cluster). By default the tests will be ran for all common commands, and with OSS standalone setup. + +To run all integration tests in a Python virtualenv, follow these steps: + + $ mkdir -p .env + $ virtualenv .env + $ source .env/bin/activate + $ pip install -r tests/test_requirements.txt + $ ./tests/run_tests.sh + +To understand what test options are available simply run: + + $ ./tests/run_tests.sh --help + +### Memory Leak Detection with Sanitizers + +memtier_benchmark supports building with AddressSanitizer (ASAN) and LeakSanitizer (LSAN) to detect memory errors and leaks during testing. + +To build with sanitizers enabled: + + $ ./configure --enable-sanitizers + $ make + +To run tests with leak detection: + + $ ASAN_OPTIONS=detect_leaks=1 ./tests/run_tests.sh + +If memory leaks or errors are detected, tests will fail with detailed error messages showing the location of the issue. + +To verify ASAN is enabled: + + $ ldd ./memtier_benchmark | grep asan + +### Undefined Behavior Detection with UBSan + +memtier_benchmark supports building with UndefinedBehaviorSanitizer (UBSan) to detect undefined behavior such as integer overflows, null pointer dereferences, and alignment issues. + +To build with UBSan enabled: + + $ ./configure --enable-ubsan + $ make + +To run tests with undefined behavior detection: + + $ UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./tests/run_tests.sh + +UBSan can be combined with ASAN for comprehensive testing: + + $ ./configure --enable-sanitizers --enable-ubsan + $ make + +**Note:** UBSan can be used together with ASAN/LSAN, but not with ThreadSanitizer (TSAN). + +### Data Race Detection with Thread Sanitizer + +memtier_benchmark supports building with ThreadSanitizer (TSAN) to detect data races and threading issues. + +To build with Thread Sanitizer enabled: + + $ ./configure --enable-thread-sanitizer + $ make + +To run tests with race detection (requires disabling ASLR on kernel 6.6+): + + $ TSAN_OPTIONS="suppressions=$(pwd)/tsan_suppressions.txt" setarch `uname -m` -R ./tests/run_tests.sh + +To verify TSAN is enabled: + + $ ldd ./memtier_benchmark | grep tsan + +**Note:** TSAN and ASAN are mutually exclusive and cannot be used together. A suppression file (`tsan_suppressions.txt`) is provided to ignore known benign data races that do not affect correctness. + diff --git a/README.md b/README.md index 9a477dd..1c63225 100644 --- a/README.md +++ b/README.md @@ -55,129 +55,7 @@ brew install memtier_benchmark ### Installing from source -#### Prerequisites - -The following libraries are required for building: - -* libevent 2.0.10 or newer. -* OpenSSL (unless TLS support is disabled by `./configure --disable-tls`). - -The following tools are required -* autoconf -* automake -* pkg-config -* GNU make -* GCC C++ compiler - -#### CentOS/Red Hat Linux 7 or newer - -Use the following to install prerequisites: -``` -$ sudo yum install autoconf automake make gcc-c++ \ - zlib-devel libmemcached-devel libevent-devel openssl-devel -``` - -#### Ubuntu/Debian - -Use the following to install prerequisites: - -``` -$ sudo apt-get install build-essential autoconf automake \ - libevent-dev pkg-config zlib1g-dev libssl-dev -``` - -#### macOS - -To build natively on macOS, use Homebrew to install the required dependencies: - -``` -$ brew install autoconf automake libtool libevent pkg-config openssl@3.0 -``` - -When running `./configure`, if it fails to find libssl it may be necessary to -tweak the `PKG_CONFIG_PATH` environment variable: - -``` -PKG_CONFIG_PATH=`brew --prefix openssl@3.0`/lib/pkgconfig ./configure -``` - -#### Building and installing - -After downloading the source tree, use standard autoconf/automake commands: - -``` -$ autoreconf -ivf -$ ./configure -$ make -$ sudo make install -``` - -#### Testing - -The project includes a basic set of integration tests. - - -**Integration tests** - - -Integration tests are based on [RLTest](https://github.com/RedisLabsModules/RLTest), and specific setup parameters can be provided -to configure tests and topologies (OSS standalone and OSS cluster). By default the tests will be ran for all common commands, and with OSS standalone setup. - - -To run all integration tests in a Python virtualenv, follow these steps: - - $ mkdir -p .env - $ virtualenv .env - $ source .env/bin/activate - $ pip install -r tests/test_requirements.txt - $ ./tests/run_tests.sh - -To understand what test options are available simply run: - - $ ./tests/run_tests.sh --help - - -**Memory leak detection with sanitizers** - - -memtier_benchmark supports building with AddressSanitizer (ASAN) and LeakSanitizer (LSAN) to detect memory errors and leaks during testing. - -To build with sanitizers enabled: - - $ ./configure --enable-sanitizers - $ make - -To run tests with leak detection: - - $ ASAN_OPTIONS=detect_leaks=1 ./tests/run_tests.sh - -If memory leaks or errors are detected, tests will fail with detailed error messages showing the location of the issue. - -To verify ASAN is enabled: - - $ ldd ./memtier_benchmark | grep asan - - -**Data race detection with Thread Sanitizer** - - -memtier_benchmark supports building with ThreadSanitizer (TSAN) to detect data races and threading issues. - -To build with Thread Sanitizer enabled: - - $ ./configure --enable-thread-sanitizer - $ make - -To run tests with race detection (requires disabling ASLR on kernel 6.6+): - - $ TSAN_OPTIONS="suppressions=$(pwd)/tsan_suppressions.txt" setarch `uname -m` -R ./tests/run_tests.sh - -To verify TSAN is enabled: - - $ ldd ./memtier_benchmark | grep tsan - -**Note:** TSAN and ASAN are mutually exclusive and cannot be used together. A suppression file (`tsan_suppressions.txt`) is provided to ignore known benign data races that do not affect correctness. - +For detailed instructions on building from source, running tests, and using sanitizers for development, see [DEVELOPMENT.md](DEVELOPMENT.md). ## Using Docker diff --git a/configure.ac b/configure.ac index a43efd6..d73b9d4 100755 --- a/configure.ac +++ b/configure.ac @@ -79,6 +79,16 @@ AS_IF([test "x$enable_sanitizers" = "xyes"], [ LDFLAGS="$LDFLAGS -fsanitize=address -fsanitize=leak" ], []) +# UndefinedBehaviorSanitizer (UBSan) is optional and can be combined with ASAN. +AC_ARG_ENABLE([ubsan], + [AS_HELP_STRING([--enable-ubsan], + [Enable UndefinedBehaviorSanitizer for undefined behavior detection])]) +AS_IF([test "x$enable_ubsan" = "xyes"], [ + AC_MSG_NOTICE([Enabling UndefinedBehaviorSanitizer]) + CXXFLAGS="$CXXFLAGS -fsanitize=undefined -fno-omit-frame-pointer" + LDFLAGS="$LDFLAGS -fsanitize=undefined" + ], []) + # Thread Sanitizer (TSAN) is optional and mutually exclusive with ASAN. AC_ARG_ENABLE([thread-sanitizer], [AS_HELP_STRING([--enable-thread-sanitizer],