Skip to content

ci: upgrade cppcheck from 2.3 to 2.13 via apt#5943

Open
fabit0v wants to merge 4 commits into
aws:mainfrom
fabit0v:cpp-check
Open

ci: upgrade cppcheck from 2.3 to 2.13 via apt#5943
fabit0v wants to merge 4 commits into
aws:mainfrom
fabit0v:cpp-check

Conversation

@fabit0v

@fabit0v fabit0v commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Goal

Update the cppcheck CI to use Ubuntu's pre-built package with incremental caching and targeted configuration checking.

Why

The build-from-source setup (pinned to cppcheck 2.3 from 2020) requires source patches and keeps breaking. Every upgrade attempt (#3630, #3646, #5186) failed due to compilation issues on newer Ubuntu.

How

  • Replace install_cppcheck.sh with apt-get install cppcheck=2.13*
  • Remove --force and replace with explicit -D/-U flags targeting Linux+AWS-LC (the largest code path)
  • Default --max-configs=12 handles remaining unknown macros (with -D/-U pinning major macros, this adds zero additional runtime)
  • Add --cppcheck-build-dir with GitHub Actions cache for incremental analysis
  • Rebuild suppressions.txt and verify against cppcheck 2.13
  • Use -j "$(nproc)" to adapt to available cores

Callouts

Why target a single config as opposed to checking everything?
Cppcheck 2.13 with --force explores every #ifdef combination. With dozens of platform/crypto macros across hundreds of files, this causes 6+ hour timeouts on CI's 2-core runners. The old version (2.3) handled --force in 28 min because its analysis was less thorough. The alternative is to explicitly define one configuration with -D/-U flags and let --max-configs=12 handle the rest. This produces identical findings to using the --force flag in 32 min as opposed to 6+ hours on the CI.

  • Cold run takes ~32 min on CI (2-core runner) on the first run. After cache is seeded it will be seconds.
  • --force removed. It caused 6+ hour timeouts with cppcheck 2.13 on 2-core runners. The -D/-U approach explicitly resolves the major platform/crypto macros that cause combinatorial explosion.
    • Running with and without --force locally produces identical findings
  • -j "$(nproc)" disables unusedFunction check (unchanged behavior from before)
  • All suppressions verified against cppcheck 2.13.0 (Ubuntu 24.04)

Testing

  • Ran locally in Docker with --cpus=2 simulating GitHub Actions runner constraints: 32 min cold run, passes clean
  • Verified --force vs single-config produces identical findings
  • Verified three-config(first commit) vs single-config(Linux + AWSLC). Single-config run results in identical findings with shorter run time.
  • CI runners verified 32 min on a cold run and 10 seconds after rerunning with cache.

Resolves #5239

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@github-actions github-actions Bot added the s2n-core team label Jun 18, 2026
@fabit0v fabit0v force-pushed the cpp-check branch 4 times, most recently from 8d45387 to 301252a Compare June 29, 2026 19:37
@fabit0v fabit0v changed the title ci: update cpp check ci: upgrade cppcheck from 2.3 to 2.13 via apt Jun 30, 2026
@fabit0v fabit0v marked this pull request as ready for review June 30, 2026 20:59

@boquan-fang boquan-fang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like cppcheck will take 1 hour 43 minutes to finish running: https://github.com/aws/s2n-tls/actions/runs/28401044354/job/84152043651?pr=5943. Will this becomes faster in the future? If so, how much time or how many PRs do we need to do to get it down to a reasonable runtime.

$CPPCHECK_EXECUTABLE --std=c99 --error-exitcode=-1 --quiet -j "$(nproc)" \
--cppcheck-build-dir="$CPPCHECK_BUILD_DIR" \
--max-configs=1 \
--enable=warning,performance,portability \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original check has --enable=all and the code that you change to only has warning, performance, and portability check. Does that drop test coverage?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It primarily drops the style suggestions which aren't actionable and informational messages like "ConfigurationNotChecked" and "unusedFunction", which don't work with -j.

Comment thread codebuild/bin/run_cppcheck.sh Outdated
if [ $FAILED == 1 ];
then

# Config 1: Linux + AWS-LC (primary customer configuration)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these three configs seem very similar to each other. Can we just use --force flag and make it one command?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--force causes the job to time out at 6 hours because it tells cppcheck to explore every possible #ifdef combination.

Comment thread .github/workflows/ci_linting.yml Outdated
Comment thread codebuild/bin/cppcheck_suppressions.txt Outdated
constParameterCallback

// Reason: Conditions always true/false due to compile-time constants or platform-dependent macros.
knownConditionTrueFalse

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At line 17 of this file: https://github.com/aws/s2n-tls/pull/5943/changes#diff-bc7696cee1ea27205e3e145964ee35b2c7e79d5184b450e2dd1d5218aaee01f1R17, knownConditionTrueFalse has already been scoped to crypto/s2n_libcrypto.c. Why do we enable it globally here? Do we want this suppression to be globally available or just scoped to crypto/s2n_libcrypto.c?

Comment thread codebuild/bin/cppcheck_suppressions.txt Outdated
nullPointerRedundantCheck:tls/s2n_tls13_secrets.c

// Reason: Const correctness suggestions are low-priority style noise. Suppressed globally.
constParameterPointer

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How many errors are these suppressing? All previous suppressions have a scope. Global suppressions might hide problems from us and general not a good idea.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of these suppressions are from using cpp-check 2.19 locally which introduced new findings. I can scope it down to what the current CI runners use (version 2.13)

Comment thread codebuild/bin/cppcheck_suppressions.txt Outdated
checkersReport

// Reason: Suppressions from old cppcheck version that no longer match.
unmatchedSuppression

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This unmatchedSuppression seems to suppress warnings if a suppression in this file doesn't match anything. I don't think we should suppress this error. We should fix the warnings that was generated by this suppression.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of these findings are results from running it locally (Ubuntu 26 uses cpp-check 2.19). I will refactor to focus on the version that the CI runners use (2.13).

@fabit0v fabit0v requested a review from boquan-fang July 9, 2026 21:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update cppcheck

2 participants