Skip to content

Fix concurrent map read/write panic in configuration map#3216

Open
nitishagar wants to merge 1 commit into
arduino:masterfrom
nitishagar:nitishagar/fix-configmap-data-race
Open

Fix concurrent map read/write panic in configuration map#3216
nitishagar wants to merge 1 commit into
arduino:masterfrom
nitishagar:nitishagar/fix-configmap-data-race

Conversation

@nitishagar

Copy link
Copy Markdown

What

Make internal/go-configmap.Map safe for concurrent use with a sync.RWMutex.

Why

The background "check for updates" goroutine started for every command reads the settings map (shouldCheckForUpdateGetBool) while config set concurrently writes and YAML-marshals the same map. This races the underlying Go map and panics with fatal error: concurrent map read and map write (reported on Windows CI in #3103).

How

  • Add a pointer *sync.RWMutex to Map (a value mutex would be copied by the value-receiver methods and protect nothing) and initialize it in New().
  • Lock at the exported entry points (Get/Set/Delete/Merge/AllKeys/Schema/SetKeyTypeSchema/Marshal*/Unmarshal* and the cli.go setters); keep the recursive helpers lock-free so the top-level lock protects the whole nested tree without deadlocking.
  • MarshalYAML/MarshalJSON return a deep snapshot so the encoder never iterates the live map after the lock is released.
  • Add TestConcurrentAccess (concurrent reader + writer + marshal), which fails under -race without the fix.

Fixes #3103

@CLAassistant

CLAassistant commented Jun 16, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

The per-command "check for updates" goroutine reads the settings map (via
shouldCheckForUpdate) while `config set` concurrently writes and YAML-marshals
the same map, causing a "concurrent map read and map write" runtime panic
(observed on Windows CI).

Make configmap.Map safe for concurrent use with a sync.RWMutex: lock at the
exported entry points and keep the recursive helpers lock-free, and have
MarshalYAML/MarshalJSON return a deep snapshot so the encoder never iterates
the live map.

Fixes arduino#3103
@nitishagar nitishagar force-pushed the nitishagar/fix-configmap-data-race branch from 4024fa1 to 0befe04 Compare June 17, 2026 02:12
@nitishagar

Copy link
Copy Markdown
Author

The only failing check here is test-integration (windows-latest, monitor), which looks like an unrelated flaky test rather than a problem with this change. The monitor integration group also flaked (on macOS) on my unrelated PR #3217, which doesn't touch this code at all, and the latest master integration run passes it.

This change only adds a sync.RWMutex to internal/go-configmap, and the new -race regression test (TestConcurrentAccess) passes locally and in CI. Could a maintainer re-run the failed job when convenient? Happy to rebase or adjust if anything is needed. Thanks!

@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.30769% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.49%. Comparing base (f9fd5c7) to head (0befe04).

Files with missing lines Patch % Lines
internal/go-configmap/cli.go 75.00% 3 Missing ⚠️
internal/go-configmap/configuration.go 94.87% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3216      +/-   ##
==========================================
+ Coverage   69.43%   69.49%   +0.06%     
==========================================
  Files         252      252              
  Lines       19595    19641      +46     
==========================================
+ Hits        13606    13650      +44     
- Misses       4718     4719       +1     
- Partials     1271     1272       +1     
Flag Coverage Δ
unit 69.49% <92.30%> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants