Skip to content
Draft
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
59 changes: 59 additions & 0 deletions .github/STATIC_ANALYSIS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Static Analysis and Code Quality CI

This workflow provides stricter code quality checks for the FSW repository.

## Jobs

### 1. Compiler Warnings (`compiler-warnings`)
- Builds all projects with `-Wall` enabled
- Catches common coding errors and potential issues at compile time
- Runs on `native_sim` platform

### 2. Address Sanitizer (`asan-build`)
- Builds and tests with AddressSanitizer (ASAN)
- Detects memory errors:
- Use-after-free
- Heap buffer overflow
- Stack buffer overflow
- Memory leaks
- Only runs on `native_sim` (Linux-only)

### 3. Undefined Behavior Sanitizer (`ubsan-build`)
- Builds and tests with UndefinedBehaviorSanitizer (UBSAN)
- Detects undefined behavior:
- Integer overflows
- Null pointer dereferences
- Invalid type casts
- Alignment violations
- Only runs on `native_sim` (Linux-only)

### 4. Valgrind Memory Checker (`valgrind-test`)
- Runs executables under Valgrind
- Additional memory error detection
- Detects memory leaks and invalid memory access
- Uses suppressions file for known Zephyr false positives

## Using Snippets Locally

You can use these analysis tools locally when building:

```bash
# Build with ASAN
west build -b native_sim app/your-app -- -DSNIPPET=asan

# Build with UBSAN
west build -b native_sim app/your-app -- -DSNIPPET=ubsan

# Build with compiler warnings
west build -b native_sim app/your-app -- -DSNIPPET=compiler-warnings
```

## Global Compiler Warnings

All builds now include `-Wall` by default through the root `CMakeLists.txt`.
This ensures production code meets stricter quality standards.

## References

- [Zephyr Static Code Analysis](https://docs.zephyrproject.org/latest/develop/sca/index.html)
- [Zephyr Native Sim with Sanitizers](https://docs.zephyrproject.org/latest/boards/native/native_sim/doc/index.html)
37 changes: 37 additions & 0 deletions .github/valgrind-zephyr.supp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Valgrind suppressions for Zephyr RTOS
# This file suppresses known false positives and Zephyr-internal behaviors

{
zephyr_thread_stack_uninitialized
Memcheck:Cond
...
fun:z_*
}

{
zephyr_syscall_uninitialized
Memcheck:Value*
...
fun:z_*
}

{
zephyr_kernel_internal
Memcheck:Addr*
...
fun:z_*
}

{
native_posix_driver
Memcheck:Leak
...
fun:*posix*
}

{
native_sim_driver
Memcheck:Leak
...
fun:*native*
}
204 changes: 204 additions & 0 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
name: Static Analysis and Sanitizer Builds

on:
push:
branches:
- main
pull_request:
branches:
- '*'
schedule:
- cron: "0 0 * * 1"

# Limit permissions to read-only for security
permissions:
contents: read

env:
# Only run on native_sim for sanitizer and analysis builds
platforms: |
native_sim

jobs:
compiler-warnings:
name: Build with -Wall Compiler Warnings
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
path: FSW
fetch-depth: 2

- name: Run Starter Steps
uses: ./FSW/.github/actions/fsw-setup

- name: Set test_roots based on changes
id: set_test_roots
shell: bash
working-directory: FSW
run: |
if [ "$GITHUB_REF_NAME" = "main" ]; then
# On main branch, run all test roots
python3 .github/scripts/determine_test_roots.py --map .github/hardware-roots.yaml --run-all > test_roots.txt
else
# On PR/branch, diff against main
git fetch origin main:refs/remotes/origin/main
git diff --name-only origin/main...HEAD > changed_files.txt
cat changed_files.txt | python3 .github/scripts/determine_test_roots.py --map .github/hardware-roots.yaml > test_roots.txt
fi
echo "test_roots<<EOF" >> $GITHUB_ENV
cat test_roots.txt >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV

- name: Build with compiler warnings
if: steps.set_test_roots.outcome == 'success' && env.test_roots != ''
working-directory: FSW
shell: bash
run: |
export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig
function add_arglist () {
echo "$2" | while read -r line; do
[ -z "$line" ] && continue
echo -n " $1 $line "
done;
}
west twister $(add_arglist -T "${{ env.test_roots }}") $(add_arglist -p "${{ env.platforms }}") -v --inline-logs --integration --extra-args="SNIPPET=compiler-warnings"

asan-build:
name: Build and Test with Address Sanitizer (ASAN)
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
path: FSW
fetch-depth: 2

- name: Run Starter Steps
uses: ./FSW/.github/actions/fsw-setup

- name: Set test_roots based on changes
id: set_test_roots
shell: bash
working-directory: FSW
run: |
if [ "$GITHUB_REF_NAME" = "main" ]; then
python3 .github/scripts/determine_test_roots.py --map .github/hardware-roots.yaml --run-all > test_roots.txt
else
git fetch origin main:refs/remotes/origin/main
git diff --name-only origin/main...HEAD > changed_files.txt
cat changed_files.txt | python3 .github/scripts/determine_test_roots.py --map .github/hardware-roots.yaml > test_roots.txt
fi
echo "test_roots<<EOF" >> $GITHUB_ENV
cat test_roots.txt >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV

- name: Build with ASAN
if: steps.set_test_roots.outcome == 'success' && env.test_roots != ''
working-directory: FSW
shell: bash
run: |
export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig
function add_arglist () {
echo "$2" | while read -r line; do
[ -z "$line" ] && continue
echo -n " $1 $line "
done;
}
west twister $(add_arglist -T "${{ env.test_roots }}") $(add_arglist -p "${{ env.platforms }}") -v --inline-logs --integration --extra-args="SNIPPET=asan"

ubsan-build:
name: Build and Test with Undefined Behavior Sanitizer (UBSAN)
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
path: FSW
fetch-depth: 2

- name: Run Starter Steps
uses: ./FSW/.github/actions/fsw-setup

- name: Set test_roots based on changes
id: set_test_roots
shell: bash
working-directory: FSW
run: |
if [ "$GITHUB_REF_NAME" = "main" ]; then
python3 .github/scripts/determine_test_roots.py --map .github/hardware-roots.yaml --run-all > test_roots.txt
else
git fetch origin main:refs/remotes/origin/main
git diff --name-only origin/main...HEAD > changed_files.txt
cat changed_files.txt | python3 .github/scripts/determine_test_roots.py --map .github/hardware-roots.yaml > test_roots.txt
fi
echo "test_roots<<EOF" >> $GITHUB_ENV
cat test_roots.txt >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV

- name: Build with UBSAN
if: steps.set_test_roots.outcome == 'success' && env.test_roots != ''
working-directory: FSW
shell: bash
run: |
export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig
function add_arglist () {
echo "$2" | while read -r line; do
[ -z "$line" ] && continue
echo -n " $1 $line "
done;
}
west twister $(add_arglist -T "${{ env.test_roots }}") $(add_arglist -p "${{ env.platforms }}") -v --inline-logs --integration --extra-args="SNIPPET=ubsan"

valgrind-test:
name: Run with Valgrind Memory Checker
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
path: FSW
fetch-depth: 2

- name: Run Starter Steps
uses: ./FSW/.github/actions/fsw-setup

- name: Install Valgrind
run: |
sudo apt-get update
sudo apt-get install -y valgrind

- name: Set test_roots based on changes
id: set_test_roots
shell: bash
working-directory: FSW
run: |
if [ "$GITHUB_REF_NAME" = "main" ]; then
python3 .github/scripts/determine_test_roots.py --map .github/hardware-roots.yaml --run-all > test_roots.txt
else
git fetch origin main:refs/remotes/origin/main
git diff --name-only origin/main...HEAD > changed_files.txt
cat changed_files.txt | python3 .github/scripts/determine_test_roots.py --map .github/hardware-roots.yaml > test_roots.txt
fi
echo "test_roots<<EOF" >> $GITHUB_ENV
cat test_roots.txt >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV

- name: Build for Valgrind
if: steps.set_test_roots.outcome == 'success' && env.test_roots != ''
working-directory: FSW
shell: bash
run: |
export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig
# Set Valgrind options to use our suppressions file
# VALGRIND_OPTS is used by Valgrind when invoked by twister
export VALGRIND_OPTS="--suppressions=${{ github.workspace }}/FSW/.github/valgrind-zephyr.supp"
function add_arglist () {
echo "$2" | while read -r line; do
[ -z "$line" ] && continue
echo -n " $1 $line "
done;
}
# Build native_sim targets without sanitizers (sanitizers and Valgrind don't mix well)
west twister $(add_arglist -T "${{ env.test_roots }}") $(add_arglist -p "${{ env.platforms }}") -v --inline-logs --integration --enable-valgrind
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ project(Backplane-Flight-Computer)
zephyr_syscall_include_directories(include)

zephyr_include_directories(include)

# Enable strict compiler warnings for all builds
zephyr_compile_options(-Wall)

add_subdirectory(drivers)
add_subdirectory(lib)
12 changes: 12 additions & 0 deletions cmake/Snippets.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,15 @@ function(AddSimSnippets)

AddSnippets(${SIM_SNIPPETS})
endfunction()

function(AddCompilerWarningsSnippets)
AddSnippets("compiler-warnings")
endfunction()

function(AddAsanSnippets)
AddSnippets("asan")
endfunction()

function(AddUbsanSnippets)
AddSnippets("ubsan")
endfunction()
3 changes: 3 additions & 0 deletions snippets/asan/asan.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Address Sanitizer configuration
CONFIG_ASAN=y
CONFIG_NO_OPTIMIZATIONS=y
3 changes: 3 additions & 0 deletions snippets/asan/snippet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: asan
append:
EXTRA_CONF_FILE: asan.conf
3 changes: 3 additions & 0 deletions snippets/compiler-warnings/compiler-warnings.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Enable compiler warnings for stricter code quality
CONFIG_COMPILER_WARNINGS_AS_ERRORS=y
CONFIG_COMPILER_COLOR_DIAGNOSTICS=y
4 changes: 4 additions & 0 deletions snippets/compiler-warnings/snippet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: compiler-warnings
append:
EXTRA_CONF_FILE: compiler-warnings.conf
EXTRA_CFLAGS: -Wall
3 changes: 3 additions & 0 deletions snippets/ubsan/snippet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: ubsan
append:
EXTRA_CONF_FILE: ubsan.conf
3 changes: 3 additions & 0 deletions snippets/ubsan/ubsan.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Undefined Behavior Sanitizer configuration
CONFIG_UBSAN=y
CONFIG_NO_OPTIMIZATIONS=y