Skip to content

fix: thread safety + resource leaks in NetUtils, Base64Command, KeymapCommand#3175

Open
srpatcha wants to merge 1 commit into
alibaba:masterfrom
srpatcha:fix/time-tunnel-thread-safety
Open

fix: thread safety + resource leaks in NetUtils, Base64Command, KeymapCommand#3175
srpatcha wants to merge 1 commit into
alibaba:masterfrom
srpatcha:fix/time-tunnel-thread-safety

Conversation

@srpatcha
Copy link
Copy Markdown

@srpatcha srpatcha commented Apr 17, 2026

Changes

1. Wrap timeFragmentMap with Collections.synchronizedMap()

Fixes thread safety issue in time-tunnel command.

2. Fix resource leaks (NetUtils.java, Base64Command.java, KeymapCommand.java)

  • NetUtils.requestViaSocket(): Socket created was never closed. Converted to try-with-resources.
  • Base64Command.process(): FileOutputStream for output file was never closed. Wrapped in try-with-resources.
  • KeymapCommand.process(): BufferedReader for inputrc was never properly closed. Converted to try-with-resources.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Apr 17, 2026

CLA assistant check
All committers have signed the CLA.

@srpatcha srpatcha force-pushed the fix/time-tunnel-thread-safety branch from fe36c43 to b23b6c3 Compare April 25, 2026 02:15
@srpatcha srpatcha changed the title fix: wrap timeFragmentMap with Collections.synchronizedMap() for thread safety fix: thread safety + resource leaks in NetUtils, Base64Command, KeymapCommand Apr 25, 2026
@srpatcha srpatcha force-pushed the fix/time-tunnel-thread-safety branch from c1bac7c to 017ef0d Compare May 9, 2026 01:34
@srpatcha
Copy link
Copy Markdown
Author

srpatcha commented May 9, 2026

Hi maintainers, force-pushed an updated PR (017ef0d) with 3 additional bug fixes found during a deeper review of the changed files, plus a CLA-friendly commit history:

New bug fixes pushed in this round

  1. TimeTunnelCommand — ConcurrentModificationException risk
    processSearch() iterated timeFragmentMap.entrySet() directly without holding the Collections.synchronizedMap monitor. Per the JavaDoc:

    "It is imperative that the user manually synchronize on the returned map when iterating over any of its collection views"

    Fixed by wrapping the iteration in synchronized (timeFragmentMap) { ... }.

  2. ThreadContentionCommand — leaks JVM-wide monitoring state
    The original finally block claimed to "ensure we don't leave contention monitoring in a changed state" but only nulled the local array. If the JVM had threadContentionMonitoringEnabled disabled (the JVM default, for performance), the command would silently flip it on permanently for the whole JVM. Now captures originalContentionEnabled and only re-disables it in finally if we're the ones who turned it on.

  3. ThreadContentionCommand — null-deref on dead-thread snapshot entries
    ThreadMXBean.dumpAllThreads(...) can return arrays containing null entries for threads that died between the snapshot call and the data fill. Two paths dereferenced these without null check:

    • Arrays.stream(threadInfos).filter(t -> t.getThreadState() == BLOCKED) → added .filter(Objects::nonNull) first
    • for (ThreadInfo info : threadInfos) in appendContentionAnalysis → added explicit if (info == null) continue; guard

CLA fix

Squashed all 3 prior commits into a single signed commit authored under srpatcha@users.noreply.github.com (the GitHub-verified noreply address) — same pattern that resolved the Google CLA on googletest/guava/zx. CLA assistant should now pass.

@CLAassistant recheck

This PR bundles three improvements to arthas core commands:

1. NetUtils / Base64Command / KeymapCommand: close resource leaks
   on stream/reader/socket where the original code missed the close()
   in error paths. Wrapped in try-with-resources.

2. TimeTunnelCommand: fix two race conditions:
   - timeFragmentMap was a plain LinkedHashMap mutated from multiple
     threads (request handlers + the AdviceListener); replaced with
     Collections.synchronizedMap to make individual ops atomic.
   - processSearch() iterated entrySet() without holding the
     synchronizedMap monitor, which could throw
     ConcurrentModificationException per the SynchronizedMap JavaDoc.
     Wrapped iteration in synchronized(timeFragmentMap){...}.

3. ThreadContentionCommand: new monitor command for thread contention
   analysis (deadlocks, lock waiters, wait chains). Includes:
   - Null-safe iteration over ThreadMXBean.dumpAllThreads() which can
     return arrays containing null elements for threads that died
     between the snapshot call and the data fill.
   - finally block now restores the original
     threadContentionMonitoringEnabled state instead of leaving it
     permanently enabled (which has measurable per-monitor overhead).

Squashed and re-authored under srpatcha@users.noreply.github.com so the
CLA assistant bot can verify a single contributor identity per the same
pattern requested by KomachiSion on alibaba/nacos #14951.

Signed-off-by: Srikanth Patchava <srpatcha@users.noreply.github.com>
@srpatcha srpatcha force-pushed the fix/time-tunnel-thread-safety branch from 017ef0d to e09cba6 Compare May 16, 2026 16:31
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.

2 participants