mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2026-02-04 05:24:56 +00:00
Add address sanitizer optional usage.
This commit is contained in:
@@ -58,6 +58,9 @@ project(libaaruformat C)
|
|||||||
# Option to enable slog logging (disabled by default)
|
# Option to enable slog logging (disabled by default)
|
||||||
option(USE_SLOG "Enable slog logging" OFF)
|
option(USE_SLOG "Enable slog logging" OFF)
|
||||||
|
|
||||||
|
# Option to enable address sanitizer (disabled by default)
|
||||||
|
option(USE_ASAN "Enable address sanitizer" OFF)
|
||||||
|
|
||||||
# Set C standard
|
# Set C standard
|
||||||
set(CMAKE_C_STANDARD 99)
|
set(CMAKE_C_STANDARD 99)
|
||||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
@@ -141,6 +144,23 @@ if("${CMAKE_BUILD_TYPE}" MATCHES "Release")
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Address sanitizer configuration
|
||||||
|
if(USE_ASAN)
|
||||||
|
message(STATUS "Address sanitizer enabled")
|
||||||
|
|
||||||
|
if("${CMAKE_C_COMPILER_ID}" MATCHES "MSVC")
|
||||||
|
# MSVC address sanitizer flags
|
||||||
|
add_compile_options(/fsanitize=address)
|
||||||
|
add_link_options(/fsanitize=address)
|
||||||
|
else()
|
||||||
|
# GCC/Clang address sanitizer flags
|
||||||
|
add_compile_options(-fsanitize=address -fno-omit-frame-pointer -g)
|
||||||
|
add_link_options(-fsanitize=address)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(STATUS "Address sanitizer disabled (enable with -DUSE_ASAN=ON)")
|
||||||
|
endif()
|
||||||
|
|
||||||
add_library(aaruformat SHARED
|
add_library(aaruformat SHARED
|
||||||
include/aaruformat/consts.h
|
include/aaruformat/consts.h
|
||||||
include/aaruformat/enums.h
|
include/aaruformat/enums.h
|
||||||
|
|||||||
39
README.md
39
README.md
@@ -43,3 +43,42 @@ Things to be implemented not in the C# version (maybe):
|
|||||||
- Snapshots
|
- Snapshots
|
||||||
- Parent images
|
- Parent images
|
||||||
- Data positioning measurements
|
- Data positioning measurements
|
||||||
|
|
||||||
|
## Building and Testing
|
||||||
|
|
||||||
|
### Standard Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake ..
|
||||||
|
cmake --build .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd build
|
||||||
|
ctest --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building with Address Sanitizer
|
||||||
|
|
||||||
|
For debugging memory issues, you can build with Address Sanitizer enabled:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir build-asan
|
||||||
|
cd build-asan
|
||||||
|
cmake -DUSE_ASAN=ON -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
|
cmake --build .
|
||||||
|
ctest --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
For detailed information on using Address Sanitizer to detect memory issues,
|
||||||
|
see [docs/ASAN_USAGE.md](docs/ASAN_USAGE.md).
|
||||||
|
|
||||||
|
### Other Build Options
|
||||||
|
|
||||||
|
- `-DUSE_SLOG=ON` - Enable slog logging for debugging
|
||||||
|
- `-DUSE_ASAN=ON` - Enable Address Sanitizer for memory error detection
|
||||||
|
|
||||||
|
|||||||
383
docs/ASAN_USAGE.md
Normal file
383
docs/ASAN_USAGE.md
Normal file
@@ -0,0 +1,383 @@
|
|||||||
|
# Address Sanitizer (ASan) Usage Guide
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Address Sanitizer (ASan) is a fast memory error detector that helps identify:
|
||||||
|
- Buffer overflows (heap, stack, and global)
|
||||||
|
- Use-after-free bugs
|
||||||
|
- Use-after-return bugs
|
||||||
|
- Use-after-scope bugs
|
||||||
|
- Double-free bugs
|
||||||
|
- Memory leaks
|
||||||
|
- Invalid pointer operations
|
||||||
|
|
||||||
|
This guide explains how to build and test libaaruformat with Address Sanitizer enabled.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
### Compiler Support
|
||||||
|
|
||||||
|
Address Sanitizer requires a modern compiler:
|
||||||
|
- **GCC**: Version 4.8 or later
|
||||||
|
- **Clang**: Version 3.1 or later
|
||||||
|
- **MSVC**: Version 16.9 or later (Visual Studio 2019 16.9+)
|
||||||
|
|
||||||
|
### Platform Support
|
||||||
|
|
||||||
|
ASan is supported on:
|
||||||
|
- Linux (x86_64, ARM, AArch64)
|
||||||
|
- macOS (x86_64, ARM64)
|
||||||
|
- Windows (x86_64, ARM64)
|
||||||
|
|
||||||
|
## Building with Address Sanitizer
|
||||||
|
|
||||||
|
### Option 1: Using CMake Command Line
|
||||||
|
|
||||||
|
Build the library and tests with ASan enabled:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create a separate build directory for ASan builds
|
||||||
|
mkdir build-asan
|
||||||
|
cd build-asan
|
||||||
|
|
||||||
|
# Configure with ASan enabled
|
||||||
|
cmake -DUSE_ASAN=ON ..
|
||||||
|
|
||||||
|
# Build the library and tests
|
||||||
|
cmake --build .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 2: Using CMake with Build Type
|
||||||
|
|
||||||
|
For additional debug information (recommended):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir build-asan
|
||||||
|
cd build-asan
|
||||||
|
|
||||||
|
# Configure with ASan and Debug build type
|
||||||
|
cmake -DUSE_ASAN=ON -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
|
|
||||||
|
# Build
|
||||||
|
cmake --build .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 3: Cross-Platform Build Script
|
||||||
|
|
||||||
|
For convenience, use the provided build script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# On Linux/macOS
|
||||||
|
./build.sh -DUSE_ASAN=ON -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
|
||||||
|
# On Windows (PowerShell)
|
||||||
|
cmake -DUSE_ASAN=ON -DCMAKE_BUILD_TYPE=Debug -B build-asan -S .
|
||||||
|
cmake --build build-asan
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running Tests with Address Sanitizer
|
||||||
|
|
||||||
|
### Basic Test Execution
|
||||||
|
|
||||||
|
Once built with ASan, run the tests normally:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd build-asan
|
||||||
|
ctest --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
Or run the test executable directly:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd build-asan/tests
|
||||||
|
./tests_run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Understanding ASan Output
|
||||||
|
|
||||||
|
When ASan detects an error, it will print a detailed report including:
|
||||||
|
|
||||||
|
1. **Error type**: e.g., "heap-buffer-overflow", "use-after-free"
|
||||||
|
2. **Stack trace**: Shows where the error occurred
|
||||||
|
3. **Memory allocation context**: Shows where the problematic memory was allocated
|
||||||
|
4. **Shadow byte legend**: Explains the memory state
|
||||||
|
|
||||||
|
Example ASan error output:
|
||||||
|
```
|
||||||
|
=================================================================
|
||||||
|
==12345==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000014 at pc 0x000000400d3c bp 0x7fff5fbff7f0 sp 0x7fff5fbff7e8
|
||||||
|
READ of size 4 at 0x602000000014 thread T0
|
||||||
|
#0 0x400d3b in main example.c:5
|
||||||
|
#1 0x7ffff7a05b44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)
|
||||||
|
#2 0x400c48 in _start (a.out+0x400c48)
|
||||||
|
|
||||||
|
0x602000000014 is located 0 bytes to the right of 4-byte region [0x602000000010,0x602000000014)
|
||||||
|
allocated by thread T0 here:
|
||||||
|
#0 0x7ffff7aaecf8 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xd9cf8)
|
||||||
|
#1 0x400d06 in main example.c:4
|
||||||
|
#2 0x7ffff7a05b44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)
|
||||||
|
=================================================================
|
||||||
|
```
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
ASan behavior can be customized using the `ASAN_OPTIONS` environment variable:
|
||||||
|
|
||||||
|
#### Detect Memory Leaks
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Enable leak detection (default on Linux, not on macOS by default)
|
||||||
|
export ASAN_OPTIONS=detect_leaks=1
|
||||||
|
./tests_run
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Continue After First Error
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# By default, ASan stops after the first error. To continue:
|
||||||
|
export ASAN_OPTIONS=halt_on_error=0
|
||||||
|
./tests_run
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Save Error Reports to File
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Save ASan reports to files instead of stderr
|
||||||
|
export ASAN_OPTIONS=log_path=/tmp/asan.log
|
||||||
|
./tests_run
|
||||||
|
# Reports will be saved as /tmp/asan.log.12345 (with PID)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Combine Multiple Options
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export ASAN_OPTIONS=detect_leaks=1:log_path=/tmp/asan.log:halt_on_error=0
|
||||||
|
./tests_run
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Useful Options Summary
|
||||||
|
|
||||||
|
| Option | Description | Default |
|
||||||
|
|--------|-------------|---------|
|
||||||
|
| `detect_leaks=1` | Enable memory leak detection | 1 (Linux), 0 (macOS) |
|
||||||
|
| `halt_on_error=0` | Continue after first error | 1 |
|
||||||
|
| `log_path=path` | Save reports to files | stderr |
|
||||||
|
| `verbosity=1` | Increase verbosity level | 0 |
|
||||||
|
| `symbolize=1` | Symbolize stack traces | 1 |
|
||||||
|
| `abort_on_error=1` | Call abort() on error | 0 |
|
||||||
|
| `print_stats=1` | Print statistics at exit | 0 |
|
||||||
|
|
||||||
|
## Platform-Specific Notes
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
ASan works out of the box on most Linux distributions. Make sure you have debug symbols installed for better stack traces:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ubuntu/Debian
|
||||||
|
sudo apt-get install binutils
|
||||||
|
|
||||||
|
# Fedora/RHEL
|
||||||
|
sudo dnf install binutils
|
||||||
|
```
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
|
||||||
|
**Important Note**: Leak detection (`detect_leaks=1`) is **not supported** on macOS. If you try to enable it, ASan will abort with an error: `AddressSanitizer: detect_leaks is not supported on this platform.`
|
||||||
|
|
||||||
|
On macOS, use ASan options without leak detection:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Correct for macOS
|
||||||
|
export ASAN_OPTIONS="print_stats=1:color=always"
|
||||||
|
|
||||||
|
# WRONG - will cause abort on macOS
|
||||||
|
export ASAN_OPTIONS="detect_leaks=1" # Don't use this!
|
||||||
|
```
|
||||||
|
|
||||||
|
For better symbolization on macOS:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install llvm-symbolizer if using Clang
|
||||||
|
brew install llvm
|
||||||
|
export PATH="/usr/local/opt/llvm/bin:$PATH"
|
||||||
|
```
|
||||||
|
|
||||||
|
System Integrity Protection (SIP) does not need to be disabled for basic ASan functionality.
|
||||||
|
|
||||||
|
### Windows (MSVC)
|
||||||
|
|
||||||
|
On Windows with MSVC, ASan requires:
|
||||||
|
|
||||||
|
1. Visual Studio 2019 version 16.9 or later
|
||||||
|
2. The "C++ AddressSanitizer" component installed
|
||||||
|
|
||||||
|
Additional MSVC-specific considerations:
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
REM Run tests in Command Prompt or PowerShell
|
||||||
|
cd build-asan\tests
|
||||||
|
.\tests_run.exe
|
||||||
|
|
||||||
|
REM For better symbols, ensure PDB files are generated
|
||||||
|
cmake -DUSE_ASAN=ON -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Issues and Solutions
|
||||||
|
|
||||||
|
### Issue: False Positives
|
||||||
|
|
||||||
|
**Problem**: ASan reports errors in third-party libraries you can't fix.
|
||||||
|
|
||||||
|
**Solution**: Use suppressions file:
|
||||||
|
|
||||||
|
1. Create a file `asan_suppressions.txt`:
|
||||||
|
```
|
||||||
|
# Suppress leak in third-party library
|
||||||
|
leak:libthirdparty.so
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Set the suppressions file:
|
||||||
|
```bash
|
||||||
|
export ASAN_OPTIONS=suppressions=./asan_suppressions.txt
|
||||||
|
./tests_run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: Performance Impact
|
||||||
|
|
||||||
|
**Problem**: Tests run significantly slower with ASan.
|
||||||
|
|
||||||
|
**Solution**: This is expected. ASan typically adds 2x-3x overhead. Use ASan builds only for debugging, not production.
|
||||||
|
|
||||||
|
### Issue: Out of Memory
|
||||||
|
|
||||||
|
**Problem**: ASan uses significant additional memory (2x-3x normal).
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
- Run fewer tests in parallel
|
||||||
|
- Increase system swap space if needed
|
||||||
|
- Test in smaller batches
|
||||||
|
|
||||||
|
### Issue: Missing Stack Traces
|
||||||
|
|
||||||
|
**Problem**: Stack traces show addresses but no symbols.
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
- Build with debug symbols: `-DCMAKE_BUILD_TYPE=Debug`
|
||||||
|
- Install `llvm-symbolizer` and ensure it's in PATH
|
||||||
|
- On Linux: Install debug packages for system libraries
|
||||||
|
|
||||||
|
## Integration with CI/CD
|
||||||
|
|
||||||
|
### GitHub Actions Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: ASan Tests
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
asan:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y cmake build-essential
|
||||||
|
|
||||||
|
- name: Build with ASan
|
||||||
|
run: |
|
||||||
|
mkdir build-asan
|
||||||
|
cd build-asan
|
||||||
|
cmake -DUSE_ASAN=ON -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
|
cmake --build .
|
||||||
|
|
||||||
|
- name: Run tests with ASan
|
||||||
|
run: |
|
||||||
|
cd build-asan
|
||||||
|
export ASAN_OPTIONS=detect_leaks=1:halt_on_error=1
|
||||||
|
ctest --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
### GitLab CI Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
asan-tests:
|
||||||
|
stage: test
|
||||||
|
script:
|
||||||
|
- mkdir build-asan && cd build-asan
|
||||||
|
- cmake -DUSE_ASAN=ON -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
|
- cmake --build .
|
||||||
|
- export ASAN_OPTIONS=detect_leaks=1:halt_on_error=1
|
||||||
|
- ctest --verbose
|
||||||
|
artifacts:
|
||||||
|
when: on_failure
|
||||||
|
paths:
|
||||||
|
- build-asan/Testing/Temporary/LastTest.log
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Regular Testing**: Run ASan builds regularly, not just when debugging
|
||||||
|
2. **Separate Build Directory**: Always use a separate build directory for ASan builds
|
||||||
|
3. **Debug Mode**: Combine ASan with Debug build type for maximum information
|
||||||
|
4. **Clean Environment**: Test with a clean environment to avoid interference
|
||||||
|
5. **Document Suppressions**: If you use suppressions, document why each one is needed
|
||||||
|
6. **CI Integration**: Add ASan tests to your CI pipeline for continuous validation
|
||||||
|
|
||||||
|
## Additional Resources
|
||||||
|
|
||||||
|
- [AddressSanitizer Documentation (Google)](https://github.com/google/sanitizers/wiki/AddressSanitizer)
|
||||||
|
- [Clang AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html)
|
||||||
|
- [GCC Instrumentation Options](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html)
|
||||||
|
- [MSVC AddressSanitizer](https://docs.microsoft.com/en-us/cpp/sanitizers/asan)
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
### Build Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Standard ASan build
|
||||||
|
cmake -DUSE_ASAN=ON -B build-asan -S .
|
||||||
|
cmake --build build-asan
|
||||||
|
|
||||||
|
# ASan build with debug symbols
|
||||||
|
cmake -DUSE_ASAN=ON -DCMAKE_BUILD_TYPE=Debug -B build-asan -S .
|
||||||
|
cmake --build build-asan
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
cd build-asan && ctest --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Enable all leak detection
|
||||||
|
export ASAN_OPTIONS=detect_leaks=1
|
||||||
|
|
||||||
|
# Save reports to files
|
||||||
|
export ASAN_OPTIONS=log_path=/tmp/asan.log
|
||||||
|
|
||||||
|
# Multiple options
|
||||||
|
export ASAN_OPTIONS=detect_leaks=1:log_path=/tmp/asan.log:halt_on_error=0
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
If you encounter issues:
|
||||||
|
|
||||||
|
1. Check compiler version supports ASan
|
||||||
|
2. Verify CMake found the correct compiler
|
||||||
|
3. Look for conflicting compiler flags
|
||||||
|
4. Check environment variables aren't interfering
|
||||||
|
5. Try with a minimal test case first
|
||||||
|
6. Review ASan documentation for your specific platform
|
||||||
|
|
||||||
|
For project-specific issues, please file a bug report with:
|
||||||
|
- Platform and compiler version
|
||||||
|
- Full CMake configuration output
|
||||||
|
- Complete ASan error report
|
||||||
|
- Steps to reproduce
|
||||||
|
|
||||||
89
run-asan-tests.ps1
Normal file
89
run-asan-tests.ps1
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# Quick script to build and run tests with Address Sanitizer on Windows
|
||||||
|
# Usage: .\run-asan-tests.ps1 [asan_options]
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# .\run-asan-tests.ps1 # Run with default ASan options
|
||||||
|
# .\run-asan-tests.ps1 "detect_leaks=1" # Enable leak detection
|
||||||
|
# .\run-asan-tests.ps1 "detect_leaks=1:halt_on_error=0" # Multiple options
|
||||||
|
|
||||||
|
param(
|
||||||
|
[string]$AsanOptions = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
# Build directory for ASan
|
||||||
|
$BuildDir = "build-asan"
|
||||||
|
|
||||||
|
Write-Host "========================================" -ForegroundColor Blue
|
||||||
|
Write-Host "Address Sanitizer Test Runner" -ForegroundColor Blue
|
||||||
|
Write-Host "========================================" -ForegroundColor Blue
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# Check if build directory exists and is configured
|
||||||
|
if (-not (Test-Path $BuildDir) -or -not (Test-Path "$BuildDir/CMakeCache.txt")) {
|
||||||
|
Write-Host "Build directory '$BuildDir' not configured. Setting up..." -ForegroundColor Yellow
|
||||||
|
New-Item -ItemType Directory -Path $BuildDir -Force | Out-Null
|
||||||
|
|
||||||
|
Write-Host "Running CMake configuration..." -ForegroundColor Blue
|
||||||
|
try {
|
||||||
|
cmake -DUSE_ASAN=ON -DCMAKE_BUILD_TYPE=Debug -B $BuildDir -S .
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Host "CMake configuration failed!" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build the project
|
||||||
|
Write-Host "Building with Address Sanitizer..." -ForegroundColor Blue
|
||||||
|
try {
|
||||||
|
cmake --build $BuildDir --config Debug
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Host "Build failed!" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Build completed successfully!" -ForegroundColor Green
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# Set up ASan options
|
||||||
|
if ($AsanOptions -ne "") {
|
||||||
|
$env:ASAN_OPTIONS = $AsanOptions
|
||||||
|
Write-Host "Using custom ASAN_OPTIONS: $env:ASAN_OPTIONS" -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Default options: detect leaks (if supported), print stats
|
||||||
|
$env:ASAN_OPTIONS = "print_stats=1"
|
||||||
|
Write-Host "Using default ASAN_OPTIONS: $env:ASAN_OPTIONS" -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Running tests..." -ForegroundColor Blue
|
||||||
|
Write-Host "========================================" -ForegroundColor Blue
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
Push-Location "$BuildDir/tests"
|
||||||
|
try {
|
||||||
|
ctest --verbose --output-on-failure -C Debug
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "========================================" -ForegroundColor Green
|
||||||
|
Write-Host "All tests passed!" -ForegroundColor Green
|
||||||
|
Write-Host "========================================" -ForegroundColor Green
|
||||||
|
Pop-Location
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "========================================" -ForegroundColor Red
|
||||||
|
Write-Host "Tests failed!" -ForegroundColor Red
|
||||||
|
Write-Host "========================================" -ForegroundColor Red
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Check the output above for Address Sanitizer reports." -ForegroundColor Yellow
|
||||||
|
Write-Host "See docs\ASAN_USAGE.md for help interpreting the results." -ForegroundColor Yellow
|
||||||
|
Pop-Location
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
90
run-asan-tests.sh
Executable file
90
run-asan-tests.sh
Executable file
@@ -0,0 +1,90 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Quick script to build and run tests with Address Sanitizer
|
||||||
|
# Usage: ./run-asan-tests.sh [asan_options]
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# ./run-asan-tests.sh # Run with default ASan options
|
||||||
|
# ./run-asan-tests.sh detect_leaks=1 # Enable leak detection
|
||||||
|
# ./run-asan-tests.sh "detect_leaks=1:halt_on_error=0" # Multiple options
|
||||||
|
|
||||||
|
set -e # Exit on error
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Build directory for ASan
|
||||||
|
BUILD_DIR="build-asan"
|
||||||
|
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo -e "${BLUE}Address Sanitizer Test Runner${NC}"
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check if build directory exists and is configured
|
||||||
|
if [ ! -d "$BUILD_DIR" ] || [ ! -f "$BUILD_DIR/CMakeCache.txt" ]; then
|
||||||
|
echo -e "${YELLOW}Build directory '$BUILD_DIR' not configured. Setting up...${NC}"
|
||||||
|
mkdir -p "$BUILD_DIR"
|
||||||
|
|
||||||
|
echo -e "${BLUE}Running CMake configuration...${NC}"
|
||||||
|
cmake -DUSE_ASAN=ON -DCMAKE_BUILD_TYPE=Debug -B "$BUILD_DIR" -S . || {
|
||||||
|
echo -e "${RED}CMake configuration failed!${NC}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build the project
|
||||||
|
echo -e "${BLUE}Building with Address Sanitizer...${NC}"
|
||||||
|
cmake --build "$BUILD_DIR" -j$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4) || {
|
||||||
|
echo -e "${RED}Build failed!${NC}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
echo -e "${GREEN}Build completed successfully!${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Set up ASan options
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
export ASAN_OPTIONS="$1"
|
||||||
|
echo -e "${YELLOW}Using custom ASAN_OPTIONS: $ASAN_OPTIONS${NC}"
|
||||||
|
else
|
||||||
|
# Default options: print stats, use colors
|
||||||
|
# Note: detect_leaks is not supported on macOS, so we don't enable it by default
|
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
export ASAN_OPTIONS="print_stats=1:color=always"
|
||||||
|
echo -e "${YELLOW}Using default ASAN_OPTIONS (macOS): $ASAN_OPTIONS${NC}"
|
||||||
|
echo -e "${YELLOW}Note: leak detection not supported on macOS${NC}"
|
||||||
|
else
|
||||||
|
export ASAN_OPTIONS="detect_leaks=1:print_stats=1:color=always"
|
||||||
|
echo -e "${YELLOW}Using default ASAN_OPTIONS: $ASAN_OPTIONS${NC}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}Running tests...${NC}"
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
cd "$BUILD_DIR/tests"
|
||||||
|
if ctest --verbose --output-on-failure; then
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}========================================${NC}"
|
||||||
|
echo -e "${GREEN}All tests passed!${NC}"
|
||||||
|
echo -e "${GREEN}========================================${NC}"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
echo -e "${RED}========================================${NC}"
|
||||||
|
echo -e "${RED}Tests failed!${NC}"
|
||||||
|
echo -e "${RED}========================================${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}Check the output above for Address Sanitizer reports.${NC}"
|
||||||
|
echo -e "${YELLOW}See docs/ASAN_USAGE.md for help interpreting the results.${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
@@ -102,10 +102,42 @@ target_include_directories(tests_run
|
|||||||
# Link libraries
|
# Link libraries
|
||||||
target_link_libraries(tests_run PRIVATE gtest gtest_main aaruformat)
|
target_link_libraries(tests_run PRIVATE gtest gtest_main aaruformat)
|
||||||
|
|
||||||
|
# Apply address sanitizer flags to tests if enabled
|
||||||
|
if(USE_ASAN)
|
||||||
|
if("${CMAKE_C_COMPILER_ID}" MATCHES "MSVC")
|
||||||
|
# MSVC address sanitizer flags for tests
|
||||||
|
target_compile_options(tests_run PRIVATE /fsanitize=address)
|
||||||
|
target_link_options(tests_run PRIVATE /fsanitize=address)
|
||||||
|
else()
|
||||||
|
# GCC/Clang address sanitizer flags for tests
|
||||||
|
target_compile_options(tests_run PRIVATE -fsanitize=address -fno-omit-frame-pointer -g)
|
||||||
|
target_link_options(tests_run PRIVATE -fsanitize=address)
|
||||||
|
endif()
|
||||||
|
message(STATUS "Address sanitizer enabled for tests")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Ensure test data is copied before running tests
|
# Ensure test data is copied before running tests
|
||||||
add_dependencies(tests_run copy_test_data)
|
add_dependencies(tests_run copy_test_data)
|
||||||
|
|
||||||
# Integrate with CTest (per-test reporting)
|
# Integrate with CTest (per-test reporting)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
include(GoogleTest)
|
include(GoogleTest)
|
||||||
gtest_discover_tests(tests_run)
|
|
||||||
|
# Configure test discovery with proper ASAN_OPTIONS
|
||||||
|
if(USE_ASAN)
|
||||||
|
# On macOS, leak detection is not supported and causes abort
|
||||||
|
# Set ASAN_OPTIONS for test discovery to avoid this
|
||||||
|
if(APPLE)
|
||||||
|
set(DISCOVERY_ASAN_OPTIONS "print_stats=0")
|
||||||
|
else()
|
||||||
|
set(DISCOVERY_ASAN_OPTIONS "detect_leaks=0:print_stats=0")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
gtest_discover_tests(tests_run
|
||||||
|
DISCOVERY_TIMEOUT 30
|
||||||
|
PROPERTIES ENVIRONMENT "ASAN_OPTIONS=${DISCOVERY_ASAN_OPTIONS}"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
gtest_discover_tests(tests_run)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user