Skip to content

Check STF and places headers for escaping exceptions - #10612

Open
andralex wants to merge 1 commit into
mainfrom
work/stf-exception-escape-tidy
Open

Check STF and places headers for escaping exceptions#10612
andralex wants to merge 1 commit into
mainfrom
work/stf-exception-escape-tidy

Conversation

@andralex

@andralex andralex commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

bugprone-exception-escape is already enabled repo-wide in .clang-tidy with WarningsAsErrors: '*', but it has never seen STF or places: the clang-tidy job analyzes translation units compiled by clang's CUDA front end, and ci/build_tidy.sh disables both subprojects there (cudax_ENABLE_CUDASTF=OFF, cudax_ENABLE_PLACES=OFF, per the existing TODO(jfaibussowit) about clang-cuda).

Rather than wait on clang-cuda support, this sweeps those headers as host C++. An escaping exception is a host-side property, so ignoring device code loses nothing, and a host parse needs no CUDA support at all — which is what lets the check cover STF while STF compilation there stays disabled. The sweep is therefore included unconditionally.

New cccl_tidy_add_header_sweep() in cmake/CCCLAddTidyTarget.cmake generates a one-line translation unit per header and analyzes it with an explicit host C++ command line, so it needs no compilation-database entry and also covers headers no translation unit happens to include. It attaches to cudax.tidy, hence to cccl.tidy, so the existing clang-tidy job picks it up with no CI configuration change.

Two details worth knowing:

  • The sweep must define _CCCL_NO_SYSTEM_HEADER. CCCL headers declare themselves system headers, clang-tidy honors that and drops every diagnostic raised inside them, so without it the sweep silently reports nothing.
  • 104 of 107 STF/places headers parse standalone as host C++. Three are excluded with reasons: two use device intrinsics (atomicCAS, threadIdx), and stackable_task_dep.cuh is not self-contained in a host parse but is still analyzed through stf.cuh.

Findings and how they were handled

The check found seven sites, all in destructors or noexcept functions, where an exception already means termination today:

Site Treatment
~dot()finish() Reports to stderr instead. Writing the DOT trace is diagnostics-only, and failing to write a debug trace should not kill the process at exit.
~localized_array() Used cuda_try (throws) three times in a destructor; now cuda_safe_call (reports and aborts), which is the convention for destructors.
meyers_singleton::instance() Was unconditionally noexcept while default-constructing a user type; now noexcept exactly when that construction is.
~logical_data_untyped_impl()erase() NOLINTNEXTLINE + rationale: a write-back failing part-way through destruction is not recoverable.
~graph_scope_guard(), ~state(), launchable_graph_scope::release() NOLINTNEXTLINE + rationale: an unmatched push or a failed graph teardown is not recoverable.

The four annotated sites are the natural home for explicit reporting; a follow-up can replace each annotation with a reporting wrapper rather than leaving the intent implicit.

Test plan

  • ninja -j 12 cudax.tidy.exception_escape — 104 targets, 43 s wall clock, clean
  • Verified the sweep fails as expected before the fixes (all seven sites reported as errors)
  • nvcc header tests for every changed header: dot.cuh, logical_data.cuh, stackable_ctx.cuh, localized_array.cuh, meyers_singleton.cuh (7 architectures)
  • Conditional noexcept on instance() verified with g++, clang++ (C++17 and C++20) and nvcc, for both a nothrow and a throwing singleton constructor
  • pre-commit run on all touched files

bugprone-exception-escape is enabled repo-wide, but the clang-tidy job analyzes
translation units compiled by clang's CUDA front end, which STF and places are
excluded from, so neither was ever checked. Sweep their headers as host C++
instead: an escaping exception is a host-side property, and a host parse needs no
CUDA support, so the check now covers STF even where STF compilation is disabled.

The sweep found seven sites. A trace file that fails to write is not worth
terminating over, so ~dot now reports instead; ~localized_array called cuda_try
where a destructor must use cuda_safe_call; meyers_singleton::instance() claimed
noexcept unconditionally while constructing a user type, and is now noexcept only
when that construction is. The remaining four terminate by design and say so.
@andralex
andralex requested review from a team as code owners August 3, 2026 18:24
@andralex
andralex requested review from arhag23 and gonidelis August 3, 2026 18:24
@andralex
andralex requested a review from caugonnet August 3, 2026 18:24
@github-project-automation github-project-automation Bot moved this to Todo in CCCL Aug 3, 2026
@copy-pr-bot

copy-pr-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@andralex

andralex commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test c6b8d4c

@cccl-authenticator-app cccl-authenticator-app Bot moved this from Todo to In Review in CCCL Aug 3, 2026
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Improved cleanup reliability for virtual memory and allocation resources.
    • Prevented exceptions from escaping during internal teardown, with failures reported safely.
    • Improved singleton exception specifications and construction retry behavior.
  • Developer Tools

    • Added automated per-header clang-tidy sweeps for targeted exception-safety checks.
    • Integrated these checks into the CUDAX build configuration.
  • Documentation

    • Documented the new header-analysis tooling and configuration options.

Walkthrough

Changes

Exception-escape linting

Layer / File(s) Summary
Header-sweep clang-tidy infrastructure
cmake/CCCLAddTidyTarget.cmake, docs/infrastructure/cmake/references/cmake_modules.rst
Adds cccl_tidy_add_header_sweep() for per-header host-C++ clang-tidy analysis. Documents its arguments and generated targets.
CUDAX sweep and teardown handling
cudax/CMakeLists.txt, cudax/cmake/cudaxTidyExceptionEscape.cmake, cudax/include/cuda/experimental/__places/*, cudax/include/cuda/experimental/__stf/*
Enables the bugprone-exception-escape sweep. Updates CUDA cleanup calls, destructor exception handling, and fatal teardown annotations.
Singleton construction exception contract
cudax/include/cuda/experimental/__utility/meyers_singleton.cuh
Adds __instance_of and makes instance() conditionally noexcept based on default constructibility. Documents construction exception and retry behavior.

Suggested reviewers: gonidelis, arhag23, caugonnet


Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
cudax/include/cuda/experimental/__utility/meyers_singleton.cuh (1)

88-95: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

suggestion: Add an explicit host/device annotation to instance().

The changed declaration still has no _CCCL_*_API marker. Because it creates a function-local static, confirm that the function is host-only and use _CCCL_HOST_API; do not use a host-device annotation unless this implementation is supported by the target CUDA toolchains. As per coding guidelines, functions must be marked with an appropriate _CCCL_*_API annotation. As per path instructions, cudax/**/* reviews must focus on host/device annotations and supported CUDA toolchain compatibility.

Sources: Coding guidelines, Path instructions


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 426b3d4a-6c91-4357-a987-6c7d7eea3505

📥 Commits

Reviewing files that changed from the base of the PR and between 5f25fb8 and c6b8d4c.

📒 Files selected for processing (10)
  • cmake/CCCLAddTidyTarget.cmake
  • cudax/CMakeLists.txt
  • cudax/cmake/cudaxTidyExceptionEscape.cmake
  • cudax/include/cuda/experimental/__places/localized_array.cuh
  • cudax/include/cuda/experimental/__places/places.cuh
  • cudax/include/cuda/experimental/__stf/internal/dot.cuh
  • cudax/include/cuda/experimental/__stf/internal/logical_data.cuh
  • cudax/include/cuda/experimental/__stf/stackable/stackable_ctx.cuh
  • cudax/include/cuda/experimental/__utility/meyers_singleton.cuh
  • docs/infrastructure/cmake/references/cmake_modules.rst

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

1 participant