test: fix LLMQ commitment log capture race#7405
Conversation
commitment_check_undersized_bitset_debug_log_test scanned its log_lines vector while its PushBackCallback was still registered. Logger callbacks run under the logger mutex from whichever thread logs, and RegTestingSetup keeps background threads (scheduler, LLMQ) alive that log concurrently, so a push_back could reallocate the vector mid-scan and invalidate the main thread's iterators, segfaulting the linux64_multiprocess unit-test job. Hold the RAII capture guard in a std::optional and reset() it after CheckLLMQCommitment returns but before reading log_lines. DeleteCallback takes the same logger mutex as callback dispatch, so once reset() returns no thread can still be mutating the vector. Exception paths keep the existing guard-destructor cleanup. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@coderabbitai review |
✅ Action performedReview finished.
|
WalkthroughThis change modifies a single test file to fix log capture timing. The Estimated code review effort: 1 (Trivial) | ~5 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ No Merge Conflicts DetectedThis PR currently has no conflicts with other open PRs. |
|
CI scope check for the red The failed job is https://github.com/dashpay/dash/actions/runs/28672149411/job/85040686108 at head Scope check: this PR changes only |
|
✅ Review complete (commit 2732bfd) |
thepastaclaw
left a comment
There was a problem hiding this comment.
Code Review
Test-only fix for a real data race in commitment_check_undersized_bitset_debug_log_test. The log-capture callback was left registered while the test thread iterated log_lines, and RegTestingSetup keeps background threads (scheduler, LLMQ) that can log concurrently. Wrapping the guard in std::optional and calling reset() before reading synchronizes through the logger mutex (both DeleteCallback and callback dispatch take m_cs), so after reset() no other thread can still mutate the vector. Exception paths retain RAII cleanup via the optional's destructor. Commit message is clear and uses the correct test: prefix.
Source: reviewers claude-general=opus (completed), codex-general=gpt-5.5[high] (failed/unparseable), claude-dash-core-commit-history=opus (completed), codex-dash-core-commit-history=gpt-5.5[high] (failed/unparseable); verifier=opus.
Note: GitHub does not allow me to approve my own PR, so this is posted as a COMMENT while preserving the verified clean review result.
Fix LLMQ Commitment Log Capture Race
Issue being fixed or feature implemented
Fixes a flaky unit-test crash seen in
linux64_multiprocess-build / Build sourcewhile running
llmq_commitment_tests/commitment_check_undersized_bitset_debug_log_test.The failure was a segmentation fault, not a Boost assertion failure. The test
captured log lines into a local vector through
LogInstance().PushBackCallbackand then scanned that vector while the callback was still registered. In
RegTestingSetup, background scheduler/LLMQ threads can log concurrently, so abackground callback could append to the vector while the test thread was
iterating it.
What was done?
Held the log-capture guard in a
std::optionaland reset it immediately afterCheckLLMQCommitmentreturns, before readinglog_lines.DeleteCallbacktakes the same logger mutex used for callback dispatch, so oncethe reset returns the test knows no logging thread is still mutating the vector.
Exception paths still get the existing RAII cleanup through the guard destructor.
How Has This Been Tested?
Tested locally on macOS arm64:
The pre-PR review gate returned
ship.Breaking Changes
None. This is test-only.
Checklist