Skip to content

Add a valgrind suppression file for the tests - #256

Merged
derobins merged 1 commit into
developfrom
derobins/valgrind_supp
Oct 18, 2026
Merged

derobins merged 1 commit into
developfrom
derobins/valgrind_supp

Conversation

@derobins

Copy link
Copy Markdown
Collaborator

test/valgrind.supp suppresses the "still reachable" blocks that valgrind reports in the unit tests and examples when it's run with --show-leak-kinds=reachable or all. None of them come from a bug in hipObject; each is memory that a library allocates once and keeps until the process exits:

  • The static constructors in ROCm's libLLVM and libclang-cpp, which the HIP runtime loads
  • The HIP runtime, while it's being loaded and during its one-time setup on the first HIP call (including hsa_init())
  • systemPlatform(), which never destroys its platform, and the dynamic loader's records of libibverbs, which the platform keeps loaded
  • OpenSSL's global state, which it keeps after curl_global_cleanup()

Every entry matches only reachable blocks, so definite, indirect, and possible leaks are always reported. The HIP and systemPlatform() entries match only allocations made under the function that does the one-time setup, so the same allocations made anywhere else are still reported. Some of those stacks are about 20 frames deep, so the file says to run valgrind with --num-callers=40 or more.

The file also says that valgrind can't run optimized Clang builds of hipObject correctly. With -ftrivial-auto-var-init=pattern, which hipObject's Clang options always add, Clang at -O1 and above copies std::format()'s arguments with the x87 instructions fldt and fstpt. Valgrind emulates the x87 registers with 64 bits instead of 80, so the copy loses bits: std::format("{}", 42) returns "0", and formatting a string can crash. A five-line std::format() program reproduces it, even with --tool=none, and runs correctly natively and with GCC. GCC builds and Clang Debug builds work.

Testing: ran ctest -T memcheck on the 26 unit tests and the get-version example with --leak-check=full --show-leak-kinds=all --errors-for-leak-kinds=all --num-callers=40, with ROCm 10.1 and valgrind 3.26. GCC Debug and Clang Debug builds passed 27/27, with no errors and no blocks still reachable. Without the file, all 27 fail. codespell is clean.

test/valgrind.supp suppresses the "still reachable" blocks that
valgrind reports in the unit tests and examples when it's run with
--show-leak-kinds=reachable or all. None of them come from a bug in
hipObject; each is memory that a library allocates once and keeps
until the process exits:

- The static constructors in ROCm's libLLVM and libclang-cpp, which
  the HIP runtime loads
- The HIP runtime, while it's being loaded and during its one-time
  setup on the first HIP call (including hsa_init())
- systemPlatform(), which never destroys its platform, and the dynamic
  loader's records of libibverbs, which the platform keeps loaded
- OpenSSL's global state, which it keeps after curl_global_cleanup()

Every entry matches only reachable blocks, so definite, indirect, and
possible leaks are always reported. The HIP and systemPlatform()
entries match only allocations made under the function that does the
one-time setup, so the same allocations made anywhere else are still
reported. Some of those stacks are about 20 frames deep, so the file
says to run valgrind with --num-callers=40 or more.

The file also says that valgrind can't run optimized Clang builds of
hipObject correctly. With -ftrivial-auto-var-init=pattern, which
hipObject's Clang options always add, Clang at -O1 and above copies
std::format()'s arguments with the x87 instructions fldt and fstpt.
Valgrind emulates the x87 registers with 64 bits instead of 80, so the
copy loses bits: std::format("{}", 42) returns "0", and formatting a
string can crash. A five-line std::format() program reproduces it, even
with --tool=none, and runs correctly natively and with GCC. GCC builds
and Clang Debug builds work.

Testing: ran ctest -T memcheck on the 26 unit tests and the
get-version example with --leak-check=full --show-leak-kinds=all
--errors-for-leak-kinds=all --num-callers=40, with ROCm 10.1 and
valgrind 3.26. GCC Debug and Clang Debug builds passed 27/27, with no
errors and no blocks still reachable. Without the file, all 27 fail.
codespell is clean.

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor
Security scan found no critical or high findings on lines changed by this pull request

View the security scan run for complete reports.

“New” means the finding is located in a changed file on an added or modified line; it is not a base-versus-head findings delta.

Copilot AI 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.

🟢 Approval recommended

The suppressions preserve lost-memory diagnostics, introduce no runtime changes, and have no unresolved findings.

No open issues 🎉

What changed in this PR

Adds Valgrind suppressions for expected library allocations retained until process exit, keeping test memory reports focused on actionable leaks.

Changes:

  • Suppresses only reachable allocations, preserving all lost-memory diagnostics.
  • Documents CTest usage, required stack depth, and optimized Clang limitations.
File Description
test/​valgrind.supp Adds scoped suppressions and instructions for memory checks.

Review effort: Balanced

@derobins
derobins merged commit 5247cb4 into develop Oct 18, 2026
31 checks passed
@derobins
derobins deleted the derobins/valgrind_supp branch October 18, 2026 03:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants