Skip to content

test: suppress QDBus watcher QThread leak in lsan - #7589

Open
PastaPastaPasta wants to merge 1 commit into
dashpay:developfrom
PastaPastaPasta:test/lsan-qdbus-watcher-qthread
Open

test: suppress QDBus watcher QThread leak in lsan#7589
PastaPastaPasta wants to merge 1 commit into
dashpay:developfrom
PastaPastaPasta:test/lsan-qdbus-watcher-qthread

Conversation

@PastaPastaPasta

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

The asan CI job's test_dash-qt still fails on develop after #7576's extended Qt suppressions: QDBusConnectionManager lazily spawns a watcher QThread whose 120-byte allocation reports with only the QThread::QThread constructor frame (the QDBus caller frames don't symbolize), so it escapes the existing QDBusConnectionManager template. Seen on develop's own CI and on every PR based on it.

Split out of #7586 per review feedback so the build fix there isn't held up by the suppression discussion.

What was done?

Added leak:QThread::QThread to test/sanitizer_suppressions/lsan with a comment tying it to the QDBus watcher.

Known limitation, flagged during #7586 review and left open for discussion here: LSan suppression templates match any allocation stack containing the named symbol, so this also masks leaks of application-constructed QThreads (e.g. src/qt/intro.cpp) in the Qt test binary. The stack cannot be scoped tighter by symbol because the QDBus frames are unsymbolized. Alternatives raised by reviewers: adopt the upstream approach from bitcoin#35937 instead of a symbol suppression. Happy to switch this PR to that shape if preferred — opening with the minimal one-liner so the pipeline unblocks while that's decided.

How Has This Been Tested?

The failing configuration is the linux64_asan CI job's test_dash-qt run; this PR's CI is the authoritative check. The suppression file is loaded via the common LSAN_OPTIONS.

Breaking Changes

None.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation
  • I have assigned this pull request to a milestone (for repository code-owners and collaborators only)

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 31d54c69-fb26-4313-a2be-bc978cb54cf5

📥 Commits

Reviewing files that changed from the base of the PR and between 76c38fa and e30887c.

📒 Files selected for processing (1)
  • test/sanitizer_suppressions/lsan

Walkthrough

The change documents a lazily spawned, unjoined watcher thread created by QDBusConnectionManager. It adds a leak:QThread::QThread LeakSanitizer suppression in test/sanitizer_suppressions/lsan.

Estimated code review effort: 1 (Trivial) | ~2 minutes

Mergeability Score: 🔵 Low · up to e3088

This change suppresses the QDBus watcher leak but may also hide unrelated application-created QThread leaks in the Qt test binary. The PR is mergeable with explicit owner awareness or follow-up to narrow the suppression.

Possibly related PRs

Suggested reviewers: knst

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the test change: suppressing the QDBus watcher QThread leak in LSan.
Description check ✅ Passed The description explains the QDBus watcher leak, the LSan suppression, testing context, known limitation, and alternatives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@thepastaclaw

thepastaclaw commented Aug 12, 2026

Copy link
Copy Markdown

✅ Final review complete — no blockers (commit e30887c)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b77f36fd64

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# QDBusConnectionManager lazily spawns a watcher QThread that is never joined
# before process exit; the manager itself is suppressed above but the thread
# object's allocation carries only the QThread constructor frame.
leak:QThread::QThread

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Scope the suppression to the QDBus watcher

In the linux64_asan Qt test, test_dash-qt exercises application shutdown while constructing product-owned threads such as ClientModel::m_thread and ClientFeeds::m_thread. LSan matches this template against every allocation stack, so leak:QThread::QThread also suppresses constructor-owned allocations for all those application QThreads; a future shutdown leak in that state would therefore pass the sanitizer job. Avoid the constructor-wide rule and prevent or isolate the QDBus watcher initialization instead.

AGENTS.md reference: AGENTS.md:L178-L180

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd suggest to do bitcoin#35937 instead of QThread - seems as leaks are forever-friends for Qt Apps

#7586 (comment)

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Final validation — Codex/Sol only (Phase 2 disabled)

The added suppression should silence the dependency-owned QDBus watcher leak and unblock the sanitizer job, but its constructor-level match also reduces LeakSanitizer coverage for application-owned QThreads created by the Qt tests. The suppression should be isolated to the QDBus initialization path rather than matching every allocation stack containing QThread::QThread.
Source: reviewer backend model gpt-5.6-sol; final verifier backend model gpt-5.6-sol. openclaw-agent/cliproxy/gpt-5.6-sol is orchestration-only and not reviewer evidence.

Validated zero-blocker Codex/Sol precheck evidence was promoted to final because Phase 2 (Sonnet/Opus) is temporarily disabled. This is Codex/Sol-only final validation, not Codex + Sonnet/Opus coverage.

Review provenance

  • Codex reviewers: gpt-5.6-sol — general (completed)
  • Verifier: gpt-5.6-sol — verifier
  • Sonnet/Opus: not run (Phase 2 disabled — temporary Codex/Sol-only final)
  • Secondary pass: disabled (temporary_phase2_sonnet_disable)

🟡 1 suggestion(s)

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `test/sanitizer_suppressions/lsan`:
- [SUGGESTION] test/sanitizer_suppressions/lsan:9: Scope the suppression to the QDBus watcher
  LeakSanitizer suppression templates match any allocation stack containing the specified symbol, so this rule also suppresses leaked constructor-owned allocations for application QThreads. The Qt tests instantiate `ClientModel`, which constructs its own `QThread` and a `ClientFeeds` instance with another `QThread`; other application paths construct additional threads. A future application leak whose allocation stack contains `QThread::QThread` would therefore be hidden by the sanitizer job. Prevent or isolate QDBus watcher initialization during the test, or use another mechanism whose identity is specific to the dependency allocation, instead of suppressing the shared constructor symbol.

# QDBusConnectionManager lazily spawns a watcher QThread that is never joined
# before process exit; the manager itself is suppressed above but the thread
# object's allocation carries only the QThread constructor frame.
leak:QThread::QThread

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Suggestion: Scope the suppression to the QDBus watcher

LeakSanitizer suppression templates match any allocation stack containing the specified symbol, so this rule also suppresses leaked constructor-owned allocations for application QThreads. The Qt tests instantiate ClientModel, which constructs its own QThread and a ClientFeeds instance with another QThread; other application paths construct additional threads. A future application leak whose allocation stack contains QThread::QThread would therefore be hidden by the sanitizer job. Prevent or isolate QDBus watcher initialization during the test, or use another mechanism whose identity is specific to the dependency allocation, instead of suppressing the shared constructor symbol.

source: ['codex']

The extended Qt suppressions from dashpay#7576 cover QDBusConnectionPrivate, QDBusConnectionManager and QLayoutPrivate, but the connection manager also lazily spawns a watcher QThread whose 120-byte allocation reports with only the QThread constructor frame, still failing test_dash-qt under asan on develop.
@PastaPastaPasta
PastaPastaPasta force-pushed the test/lsan-qdbus-watcher-qthread branch from b77f36f to e30887c Compare August 12, 2026 23:03
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.

3 participants