Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 12 additions & 17 deletions .github/workflows/build-and-test-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,21 +76,16 @@ jobs:
-DFUSILLI_SYSTEMS_AMDGPU=ON
-DFUSILLI_ENABLE_ASAN=ON
asan-env: >-
ASAN_SYMBOLIZER_PATH=/workspace/.cache/docker/venv/bin/llvm-symbolizer-22
ASAN_OPTIONS=detect_leaks=1:halt_on_error=0
LSAN_OPTIONS=suppressions=/workspace/build_tools/sanitizers/lsan_suppressions.txt
- name: cpu_clang18_asan
runs-on: azure-linux-scale
cmake-options:
-DCMAKE_C_COMPILER=clang-18
-DCMAKE_CXX_COMPILER=clang++-18
-DCMAKE_BUILD_TYPE=Debug
-DFUSILLI_SYSTEMS_AMDGPU=OFF
-DFUSILLI_ENABLE_ASAN=ON
asan-env: >-
ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-18
ASAN_OPTIONS=detect_leaks=1:halt_on_error=0
LSAN_OPTIONS=suppressions=/workspace/build_tools/sanitizers/lsan_suppressions.txt

steps:
- name: Checkout fusilli
Expand All @@ -105,21 +100,29 @@ jobs:
cmake --build build --target all"

- name: Test fusilli (libIREECompiler CAPI)
if: ${{ matrix.name != 'cpu_gcc13_codecov' && matrix.name != 'gfx942_clang22_asan' && matrix.name != 'cpu_clang18_asan' }}
if: ${{ !contains(matrix.name, 'codecov') && !contains(matrix.name, 'asan') }}
run: |
build_tools/docker/exec_docker_ci.sh \
bash -c "ctest --test-dir build --output-on-failure --extra-verbose --timeout 120 -j \$(nproc) && \
tests/test_cache_empty.sh"

- name: Test fusilli (iree-compile CLI)
if: ${{ matrix.name != 'cpu_gcc13_codecov' && matrix.name != 'gfx942_clang22_asan' && matrix.name != 'cpu_clang18_asan' }}
if: ${{ !contains(matrix.name, 'codecov') && !contains(matrix.name, 'asan') }}
run: |
build_tools/docker/exec_docker_ci.sh \
bash -c "FUSILLI_COMPILE_BACKEND_USE_CLI=1 ctest --test-dir build --output-on-failure --extra-verbose --timeout 120 -j \$(nproc) && \
tests/test_cache_empty.sh"

- name: Run AddressSanitizer (ASan)
if: ${{ contains(matrix.name, 'asan') }}
run: |
build_tools/docker/exec_docker_ci.sh \
bash -c "${{ matrix.asan-env }} \
ctest --test-dir build --output-on-failure --extra-verbose --timeout 120 -j \$(nproc) && \
tests/test_cache_empty.sh"

- name: Run code coverage
if: ${{ matrix.name == 'cpu_gcc13_codecov' }}
if: ${{ contains(matrix.name, 'codecov') }}
run: |
build_tools/docker/exec_docker_ci.sh \
bash -c "ctest --test-dir build -T test -T coverage --timeout 120 && \
Expand All @@ -128,16 +131,8 @@ jobs:
genhtml build/coverage.info --output-directory coverage_report"

- name: Upload code coverage report
if: ${{ matrix.name == 'cpu_gcc13_codecov' }}
if: ${{ contains(matrix.name, 'codecov') }}
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: coverage-report
path: ${{ github.workspace }}/coverage_report

- name: Run AddressSanitizer
if: ${{ matrix.name == 'gfx942_clang22_asan' || matrix.name == 'cpu_clang18_asan' }}
run: |
build_tools/docker/exec_docker_ci.sh \
bash -c "${{ matrix.asan-env }} \
ctest --test-dir build --output-on-failure --extra-verbose --timeout 120 -j \$(nproc) && \
tests/test_cache_empty.sh"
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ endif()
set(FUSILLI_SANITIZER_COMPILE_FLAGS "")
set(FUSILLI_SANITIZER_LINK_FLAGS "")
if(FUSILLI_ENABLE_ASAN)
message(STATUS "AddressSanitizer enabled")
message(STATUS "AddressSanitizer (ASan) enabled")
# TODO: Remove the compilation flags "-mllvm -asan-globals=0" when
# the problem with "__asan_register_globals" (odr-violation) is fixed
list(APPEND FUSILLI_SANITIZER_COMPILE_FLAGS -fsanitize=address -fno-omit-frame-pointer -g -mllvm -asan-globals=0)
Expand Down
39 changes: 15 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,38 +245,33 @@ FUSILLI_COMPILE_BACKEND_USE_CLI=1 \
-f commands.txt
```

### Sanitizers (AddressSanitizer)
### Sanitizers

Fusilli supports building with AddressSanitizer (ASAN) for detecting memory errors such as use-after-free, buffer overflows, and memory leaks.
Fusilli supports building with [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html)
(ASan) for detecting memory errors such as use-after-free, buffer overflows, and memory leaks.

To build with AddressSanitizer, specify the cmake flag `-DFUSILLI_ENABLE_ASAN=ON`:
```shell
cmake -GNinja -S. -Bbuild \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_BUILD_TYPE=Debug \
-DFUSILLI_ENABLE_ASAN=ON \
-DIREE_SOURCE_DIR=</path/to/iree/source>
cmake --build build --target all
ctest --test-dir build
```
To build with ASan, specify the cmake flag `-DFUSILLI_ENABLE_ASAN=ON`.

To customize AddressSanitizer behavior at runtime, use the `ASAN_OPTIONS` environment variable:
Use the `ASAN_OPTIONS` environment variable to customize ASan behavior at runtime:
```shell
ASAN_OPTIONS=detect_leaks=1:halt_on_error=0 LSAN_OPTIONS=suppressions=build_tools/sanitizers/lsan_suppressions.txt ctest --test-dir build
ASAN_OPTIONS=detect_leaks=1:halt_on_error=0 \
ctest --test-dir build
```

To make AddressSanitizer symbolize its output you need to set the `ASAN_SYMBOLIZER_PATH` environment variable
to point to the llvm-symbolizer binary (or make sure llvm-symbolizer is in your `$PATH`):
Ensure `llvm-symbolizer` is in your `$PATH` (or set the `ASAN_SYMBOLIZER_PATH`
environment variable) to get symbolized stack traces from ASan:
```shell
ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer ...
ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer \
ctest --test-dir build
```

[LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html) suppressions
(`build_tools/sanitizers/lsan_suppressions.txt`) are automatically applied to
all test and benchmark targets when ASan is enabled.

> [!NOTE]
> - Debug builds (`-DCMAKE_BUILD_TYPE=Debug`) provide better stack traces.
> - Sanitizer builds have runtime overhead and are intended for development/testing, not production.
> - AddressSanitizer and Code Coverage cannot be used simultaneously, because both add heavy runtime instrumentation
and combining them often leads to slow/flaky tests and less reliable diagnostics.

### Code Coverage (using gcov + lcov)

Expand Down Expand Up @@ -312,10 +307,6 @@ lcov --remove build/coverage.info '/usr/*' '*/iree/*' --output-file build/covera
genhtml build/coverage.info --output-directory coverage_report
```

> [!NOTE]
> - AddressSanitizer and Code Coverage cannot be used simultaneously, because both add heavy runtime instrumentation
and combining them often leads to slow/flaky tests and less reliable diagnostics.

### Lint

This project is set up to use [pre-commit](https://pre-commit.com/) hooks for
Expand Down
6 changes: 6 additions & 0 deletions build_tools/cmake/FusilliTestUtils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ function(add_fusilli_benchmark)
if(FUSILLI_ENABLE_LOGGING)
list(APPEND _ENV_VARS "FUSILLI_LOG_INFO=1" "FUSILLI_LOG_FILE=stdout")
endif()
if(FUSILLI_ENABLE_ASAN)
list(APPEND _ENV_VARS "LSAN_OPTIONS=suppressions=${PROJECT_SOURCE_DIR}/build_tools/sanitizers/lsan_suppressions.txt")
endif()

# Set environment variables for test
set_tests_properties(
Expand Down Expand Up @@ -320,6 +323,9 @@ function(_add_fusilli_ctest_target)
if(FUSILLI_ENABLE_LOGGING)
list(APPEND _ENV_VARS "FUSILLI_LOG_INFO=1" "FUSILLI_LOG_FILE=stdout")
endif()
if(FUSILLI_ENABLE_ASAN)
list(APPEND _ENV_VARS "LSAN_OPTIONS=suppressions=${PROJECT_SOURCE_DIR}/build_tools/sanitizers/lsan_suppressions.txt")
endif()

# Set environment variables for test
set_tests_properties(
Expand Down
Loading