Skip to content

[SharovBot] db/state: fix DATA RACE in closeFilesAndRemove - #21465

Closed
erigon-copilot[bot] wants to merge 1 commit into
mainfrom
erigon-copilot/fix-race-closefiles-sync-once
Closed

erigon-copilot[bot] wants to merge 1 commit into
mainfrom
erigon-copilot/fix-race-closefiles-sync-once

Conversation

@erigon-copilot

Copy link
Copy Markdown
Contributor

Summary

  • Fix DATA RACE in FilesItem.closeFilesAndRemove() by wrapping the method body with sync.Once, preventing concurrent double-close of file descriptors and mmap handles
  • The race was between two goroutines reaching closeFilesAndRemove() on the same FilesItem through the old per-file refcntDecrement path (TOCTOU between canDelete and refcount atomics)
  • The bundle-level refcount redesign (aggregatorVisible.refcnt) structurally prevents this for the main code path, but sync.Once provides defense-in-depth for edge cases and the forkable/snap_repo subsystem which still uses the old pattern

Test plan

  • go test -race -count=3 -run TestHistoryVerification_SimpleBlocks ./execution/verify/... passes with no DATA RACE warnings
  • go build ./... passes
  • No test files modified

🤖 Generated with Claude Code

…via sync.Once

The race detector caught two goroutines concurrently executing
closeFilesAndRemove() on the same FilesItem through the
visibleFiles.refcntDecrement() → closeFilesAndRemove() path.
This was a TOCTOU in the old per-file refcount/canDelete mechanism:
deleteMergeFile sets canDelete=true then checks refcount==0, while
refcntDecrement decrements refcount to 0 then checks canDelete —
both observe (refcount==0, canDelete==true) and both enter
closeFilesAndRemove(), racing on Decompressor.Close() and other
fields.

The bundle-level refcount redesign (aggregatorVisible.refcnt)
structurally prevents this for the main code path, but the old
per-file mechanism is still used by the forkable/snap_repo
subsystem. Wrapping closeFilesAndRemove in sync.Once provides
defense-in-depth: even if two code paths attempt to close the
same FilesItem concurrently, only one executes the destructive
logic while the other blocks and returns.

Fixes the DATA RACE in TestHistoryVerification_SimpleBlocks
(execution/verify).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Co-authored-by: Giulio Rebuffo <giulio.rebuffo@gmail.com>
@erigon-copilot

Copy link
Copy Markdown
Contributor Author

[SharovBot] Closing this PR as superseded by #21397, which already contains the fix.

@erigon-copilot erigon-copilot Bot closed this May 28, 2026
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.

0 participants