signal: fix data race in logger during shutdown by Euler-B · Pull Request #10866 · lightningnetwork/lnd · GitHub
Skip to content

signal: fix data race in logger during shutdown#10866

Open
Euler-B wants to merge 1 commit into
lightningnetwork:masterfrom
Euler-B:fix/6137-signal-data-race
Open

signal: fix data race in logger during shutdown#10866
Euler-B wants to merge 1 commit into
lightningnetwork:masterfrom
Euler-B:fix/6137-signal-data-race

Conversation

@Euler-B

@Euler-B Euler-B commented May 31, 2026

Copy link
Copy Markdown
Contributor

Fix data race in the signal package logger during shutdown (issue #6137).

The mainInterruptHandler goroutine reads the package-level log variable while UseLogger() 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 -race flag.

The Problem

When lnd starts:

  1. signal.Intercept() spawns mainInterruptHandler goroutine which reads log to handle shutdown signals
  2. Main goroutine calls SetupLoggers()signal.UseLogger() which writes to log
  3. Both goroutines access the same log variable without synchronization

This race was reported in issue #6137 and can be reproduced by:

  • Building lnd with -race flag
  • Running lnd in simnet with btcd backend
  • Sending SIGINT during early startup

The Solution

Add a sync.RWMutex to protect concurrent access to the log variable:

  • UseLogger() acquires write lock when replacing the logger
  • New getLogger() helper acquires read lock when accessing the logger
  • All direct log accesses in signal.go replaced with getLogger() calls

This ensures thread-safe access while maintaining good performance (read-heavy workload benefits from RWMutex).

Fixes #6137

Steps to Test

  1. Build lnd with race detector:

    go build -race -o lnd-race ./cmd/lnd
  2. Start btcd in simnet:

    btcd --simnet --rpcuser=devuser --rpcpass=devpass \
      --rpclisten=127.0.0.1:18556 --listen=127.0.0.1:18555 \
      --rpccert=/tmp/btcd/rpc.cert --rpckey=/tmp/btcd/rpc.key \
      --txindex
  3. Start lnd with race detector:

    ./lnd-race --bitcoin.simnet --bitcoin.node=btcd \
      --btcd.rpcuser=devuser --btcd.rpcpass=devpass \
      --btcd.rpchost=127.0.0.1:18556 \
      --btcd.rpccert=/tmp/btcd/rpc.cert \
      --noseedbackup
  4. Send SIGINT during startup:

    kill -SIGINT <lnd-pid>
  5. Verify no data race warnings appear in logs related to signal/signal.go or signal/log.go

Before the fix: Data race detected between mainInterruptHandler (read) and UseLogger (write)

After the fix: No data race warnings

Pull Request Checklist

Testing

  • Your PR passes all CI checks.
  • Tests covering the positive and negative (error paths) are included.
  • Bug fixes contain tests triggering the bug to prevent regressions.

Code Style and Documentation

@gemini-code-assist

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist 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.

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.

Comment thread signal/log.go
@github-actions github-actions Bot added the severity-medium Focused review required label May 31, 2026
@github-actions

Copy link
Copy Markdown

PR Severity: MEDIUM

Automated classification | 3 files | 51 lines changed

Medium files (2):

  • signal/log.go - signal package logging (uncategorized Go package)
  • signal/signal.go - signal handling changes (uncategorized Go package)

Low files (1):

  • docs/release-notes/release-notes-0.22.0.md - release notes

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.
<!-- pr-severity-bot -->

@Euler-B Euler-B force-pushed the fix/6137-signal-data-race branch from c4f197e to 29b9c8b Compare May 31, 2026 19:08
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
@Euler-B Euler-B force-pushed the fix/6137-signal-data-race branch from 29b9c8b to 1d28133 Compare June 8, 2026 15:58
@lightninglabs-deploy

Copy link
Copy Markdown
Collaborator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

severity-medium Focused review required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

signal: data-race during shutdown

2 participants