Skip to content

ADFA-3130 | Fix memory usage chart crash#1470

Merged
jatezzz merged 3 commits into
stagefrom
fix/ADFA-3130-safe-line-chart
Jul 3, 2026
Merged

ADFA-3130 | Fix memory usage chart crash#1470
jatezzz merged 3 commits into
stagefrom
fix/ADFA-3130-safe-line-chart

Conversation

@jatezzz

@jatezzz jatezzz commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Description

Replaced the standard MPAndroidChart LineChart with a custom SafeLineChart in layout_mem_usage.xml. This prevents the IDE from crashing due to an IndexOutOfBoundsException caused by an axis-rendering race condition in the MPAndroidChart library. This race condition is typically triggered when Sentry Session Replay records the screen drawing on a background thread concurrently with main-thread updates.

Details

  • Created SafeLineChart.kt which extends LineChart.
  • Overrode onDraw() with a try-catch block to swallow the transient IndexOutOfBoundsException and skip the corrupted frame.
  • Added a throttled warning log (once every 60 skipped frames) to monitor the dropped frames without flooding logcat.
Screen.Recording.2026-07-02.at.9.41.53.AM.mov

Ticket

ADFA-3130

Observation

Because the memory chart is a non-critical diagnostic view, dropping an occasional frame is much safer than crashing the entire IDE. The view cleanly recovers on the next invalidate() call.

@claude claude 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.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@jatezzz jatezzz force-pushed the fix/ADFA-3130-safe-line-chart branch from eef2deb to b7a06d4 Compare July 2, 2026 20:40
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 42cbb3f4-2fa0-4137-8d5f-e223c79aa21e

📥 Commits

Reviewing files that changed from the base of the PR and between b7a06d4 and 791369b.

📒 Files selected for processing (2)
  • app/src/main/java/com/itsaky/androidide/ui/SafeLineChart.kt
  • app/src/main/res/layout/layout_mem_usage.xml
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/src/main/java/com/itsaky/androidide/ui/SafeLineChart.kt
  • app/src/main/res/layout/layout_mem_usage.xml

📝 Walkthrough
  • Replaced the memory usage chart’s standard LineChart with a new SafeLineChart wrapper to prevent crashes during transient MPAndroidChart axis-rendering race conditions.

  • SafeLineChart now catches IndexOutOfBoundsException during onDraw() and skips the corrupted frame instead of crashing the app; the chart can recover on the next invalidate().

  • Added throttled warning logging so skipped frames are reported only once every 60 occurrences, reducing log spam while still surfacing the issue.

  • Updated layout_mem_usage.xml to use com.itsaky.androidide.ui.SafeLineChart for the embedded memory chart.

  • Risk / best-practice note: swallowing exceptions in rendering code can hide underlying library defects and make debugging harder; this is acceptable here because the chart is non-critical, but the race condition should still be monitored and addressed upstream if possible.

Walkthrough

Adds a SafeLineChart subclass that catches IndexOutOfBoundsException during chart drawing and logs skipped frames periodically. The memory usage layout now uses this view instead of LineChart.

Changes

Safe chart rendering

Layer / File(s) Summary
SafeLineChart implementation
app/src/main/java/com/itsaky/androidide/ui/SafeLineChart.kt
Adds SafeLineChart with constructors, explanatory comments, a skipped-frame counter, and an onDraw guard around super.onDraw(canvas).
Layout wiring
app/src/main/res/layout/layout_mem_usage.xml
Swaps the chart widget used by @+id/chart from LineChart to SafeLineChart.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Poem

I’m a rabbit with a chart-safe grin,
When axes race, I let frames spin.
One little guard keeps crashes light,
And logs a wink every sixtieth bite. 🐰

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: fixing the memory usage chart crash.
Description check ✅ Passed The description matches the changeset and explains the SafeLineChart crash fix and logging behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/ADFA-3130-safe-line-chart

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
app/src/main/java/com/itsaky/androidide/ui/SafeLineChart.kt (1)

54-65: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Non-atomic counter racing with the exact hazard being guarded against.

skippedFrames++ is a non-atomic read-modify-write. Per this class's own documentation, onDraw can be invoked concurrently from more than one thread (main + Sentry Session Replay background thread) — the same condition that causes the IndexOutOfBoundsException being caught here. Concurrent increments can lose updates or produce an inconsistent log cadence/count. Impact is limited to logging accuracy (not a crash), so this is low priority, but consider making the counter atomic for correctness.

🔧 Optional fix using an atomic counter
-  private var skippedFrames = 0L
+  private val skippedFrames = java.util.concurrent.atomic.AtomicLong(0)
 
   override fun onDraw(canvas: Canvas) {
     try {
       super.onDraw(canvas)
     } catch (e: IndexOutOfBoundsException) {
       // Transient race in MPAndroidChart's axis renderer (see class doc). Skip this frame.
       // Only log occasionally to avoid flooding logcat, since onDraw runs every frame.
-      if (skippedFrames++ % 60L == 0L) {
-        log.warn("Skipped {} chart frame(s) due to a transient axis-rendering race", skippedFrames, e)
+      val count = skippedFrames.incrementAndGet()
+      if (count % 60L == 1L) {
+        log.warn("Skipped {} chart frame(s) due to a transient axis-rendering race", count, e)
       }
     }
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/main/java/com/itsaky/androidide/ui/SafeLineChart.kt` around lines 54
- 65, The skippedFrames counter in SafeLineChart.onDraw is being updated with a
non-atomic read-modify-write while the method may run concurrently, so replace
the plain Long counter with an atomic counter and use its atomic increment/read
APIs when deciding whether to log. Keep the fix localized to the onDraw override
and the skippedFrames field so the log cadence and count remain correct under
concurrent draws.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@app/src/main/java/com/itsaky/androidide/ui/SafeLineChart.kt`:
- Around line 54-65: The skippedFrames counter in SafeLineChart.onDraw is being
updated with a non-atomic read-modify-write while the method may run
concurrently, so replace the plain Long counter with an atomic counter and use
its atomic increment/read APIs when deciding whether to log. Keep the fix
localized to the onDraw override and the skippedFrames field so the log cadence
and count remain correct under concurrent draws.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 659e7bd9-f6bf-4868-b503-acebb37eb279

📥 Commits

Reviewing files that changed from the base of the PR and between 4f91915 and b7a06d4.

📒 Files selected for processing (2)
  • app/src/main/java/com/itsaky/androidide/ui/SafeLineChart.kt
  • app/src/main/res/layout/layout_mem_usage.xml

Introduced SafeLineChart to safely catch IndexOutOfBoundsException caused by MPAndroidChart thread-safety issues.
@jatezzz jatezzz force-pushed the fix/ADFA-3130-safe-line-chart branch from b7a06d4 to 69fa4e4 Compare July 2, 2026 20:46
@jatezzz jatezzz merged commit bf89f5b into stage Jul 3, 2026
2 checks passed
@jatezzz jatezzz deleted the fix/ADFA-3130-safe-line-chart branch July 3, 2026 15:02
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