signal: fix data race in logger during shutdown#10866
Conversation
There was a problem hiding this comment.
Code Review
This pull request addresses a data race in the signal package logger by introducing a read-write mutex (logMtx) to protect the global log variable and replacing direct accesses with a thread-safe getLogger() helper. The reviewer suggested adding a nil check in getLogger() to return btclog.Disabled as a safe default and prevent potential nil-pointer dereferences.
PR Severity: MEDIUM
Medium files (2):
Low files (1):
Analysis: The PR modifies the signal package (OS signal processing). Not in critical/high categories, so MEDIUM. No bump conditions triggered (3 files, 51 lines). Release notes are LOW but do not raise overall severity. To override, add a severity-override-{critical,high,medium,low} label. |
c4f197e to
29b9c8b
Compare
Add sync.RWMutex to protect concurrent access to the package-level logger variable. The mainInterruptHandler goroutine reads the logger while UseLogger() writes it during startup, causing a data race. Changes: - Add logMtx (sync.RWMutex) to protect log variable - Wrap UseLogger() writes with Lock/Unlock - Add getLogger() helper that uses RLock/RUnlock for thread-safe reads - Replace all direct log access in signal.go with getLogger() calls Fixes lightningnetwork#6137
29b9c8b to
1d28133
Compare

Fix data race in the signal package logger during shutdown (issue #6137).
The
mainInterruptHandlergoroutine reads the package-levellogvariable whileUseLogger()may be called from the main goroutine during startup to replace the logger with a properly configured one. This concurrent access without synchronization causes a data race when lnd is built with the-raceflag.The Problem
When lnd starts:
signal.Intercept()spawnsmainInterruptHandlergoroutine which readslogto handle shutdown signalsSetupLoggers()→signal.UseLogger()which writes tologlogvariable without synchronizationThis race was reported in issue #6137 and can be reproduced by:
-raceflagThe Solution
Add a
sync.RWMutexto protect concurrent access to thelogvariable:UseLogger()acquires write lock when replacing the loggergetLogger()helper acquires read lock when accessing the loggerlogaccesses insignal.goreplaced withgetLogger()callsThis ensures thread-safe access while maintaining good performance (read-heavy workload benefits from
RWMutex).Fixes #6137
Steps to Test
Build lnd with race detector:
Start btcd in simnet:
Start lnd with race detector:
Send SIGINT during startup:
Verify no data race warnings appear in logs related to
signal/signal.goorsignal/log.goBefore the fix: Data race detected between
mainInterruptHandler(read) andUseLogger(write)After the fix: No data race warnings
Pull Request Checklist
Testing
Code Style and Documentation
[skip ci]in the commit message for small changes.