Skip to content

Fix Performance page loading forever when the systrace recorder is in use - #10054

Open
ishaquehassan wants to merge 1 commit into
flutter:masterfrom
ishaquehassan:fix/6524-systrace-recorder-performance-hang
Open

ishaquehassan wants to merge 1 commit into
flutter:masterfrom
ishaquehassan:fix/6524-systrace-recorder-performance-hang

Conversation

@ishaquehassan

Copy link
Copy Markdown
Contributor

Fixes #6524
Fixes #9927

When the app uses a timeline recorder that doesn't keep events in the VM (systrace via --trace-systrace, or Android with ATrace already on at startup like in #9927), the VM answers getPerfettoVMTimeline with RPC error 114 (kInvalidTimelineRequest). Nothing caught it, so TimelineEventsController.init threw, PerformanceController._initHelper bailed out of its .wait before subscribing to Flutter.Frame events, and initialized never completed. That's the endless spinner on the Performance page.

Following @bkonyi's suggestion in #6524, this gates on that response:

  • _forceRefresh and the polling rate limiter now go through _maybePullPerfettoVmTimeline, which catches only RPCErrors with RPCErrorKind.kInvalidTimelineRequest.code and rethrows anything else. On that error it remembers that the VM timeline is unavailable, logs the VM's reason, and shows a dismissible notification saying timeline events aren't available because the app uses a recorder like systrace, and that restarting without system tracing brings them back.
  • _initForServiceConnection doesn't start the polling timer in that case, and the "events occurred too long ago" warning on frame selection is skipped, since that advice doesn't apply.

With init no longer throwing, the controller finishes initializing and listens for frame and rebuild events as usual, so only the Timeline Events tab stays empty. I checked the RPCs against a real VM started with --timeline_recorder=systrace: both getPerfettoVMTimeline and the DDS getPerfettoVMTimelineWithCpuSamples call (used when "Include CPU samples" is on) return code 114, while setVMTimelineFlags, getVMTimelineMicros and clearVMTimeline still succeed, so nothing else in init needed changes. I haven't run the DevTools UI against a systrace app, so there are no screenshots.

The new test in timeline_events_controller_test.dart mocks the service to throw that error and checks that init() completes, that a second refresh doesn't hit the VM again, and that the notification is shown. It fails on master with the same getPerfettoVMTimeline: (114) error from the issue. timeline_events_controller_test.dart passes 4/4 and test/screens/performance/ passes 111/111.

Pre-launch Checklist

General checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read the Flutter Style Guide recently, and have followed its advice.
  • I signed the CLA.
  • I updated/added relevant documentation (doc comments with ///).

Issues checklist

Tests checklist

  • I added new tests to check the change I am making...
  • OR there is a reason for not adding tests, which I explained in the PR description.

AI-tooling checklist

  • I did not use any AI tooling in creating this PR.
  • OR I did use AI tooling, and...
    • I read the AI contributions guidelines and agree to follow them.
    • I reviewed all AI-generated code before opening this PR.
    • I understand and am able to discuss the code in this PR.
    • I have verifed the accuracy of any AI-generated text included in the PR description.
    • I commit to verifying the accuracy of any AI-generated code or text that I upload in response to review comments.

Feature-change checklist

  • This PR does not change the DevTools UI or behavior and...
    • I added the release-notes-not-required label or left a comment requesting the label be added.
  • OR this PR does change the DevTools UI or behavior and...
    • I added an entry to packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md.
    • I included before/after screenshots and/or a GIF demo of the new UI to my PR description.
    • I ran the DevTools app locally to manually verify my changes.

build.yaml badge

If you need help, consider asking for help on Discord.

@ishaquehassan
ishaquehassan requested review from a team and kenzieschmoll as code owners October 21, 2026 21:53
@ishaquehassan
ishaquehassan requested review from srawlins and removed request for a team October 21, 2026 21:53

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

Code Review

This pull request prevents the Performance page from loading indefinitely when the connected app uses a timeline recorder (such as systrace) that does not store events in the Dart VM. It handles the kInvalidTimelineRequest RPC error, stops polling attempts, and displays a warning notification to the user. The feedback suggests optimizing resource usage by canceling the background polling timer and disposing of the rate limiter once the timeline is determined to be unavailable. Additionally, the release notes entry should be updated to link to the pull request instead of the issue, in accordance with the repository's style guide.

Comment on lines +190 to +192
_vmTimelineUnavailable = true;
_log.info(e.details ?? e.message);
pushVmTimelineUnavailableWarning();

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.

medium

[CONCERN] When the VM timeline is determined to be unavailable, we should cancel the periodic polling timer and dispose of the rate limiter. This avoids leaving a useless periodic timer running every 10 seconds in the background.

      _vmTimelineUnavailable = true;
      _pollingTimer?.cancel();
      _pollingTimer = null;
      _timelinePollingRateLimiter?.dispose();
      _timelinePollingRateLimiter = null;
      _log.info(e.details ?? e.message);
      pushVmTimelineUnavailableWarning();

Comment on lines +27 to +29
* Fixed the Performance page loading forever when the connected app uses a
timeline recorder that DevTools cannot read from, such as systrace.
[#6524](https://github.com/flutter/devtools/issues/6524)

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.

medium

[NIT] According to the DevTools release notes guidelines, the link following the entry should be the PR link (e.g., [#PR_NUMBER](https://github.com/flutter/devtools/pull/PR_NUMBER)) rather than the issue link. Please update this with the PR number once it is available.

References
  1. The release notes guidelines specify that the PR link should follow the sentence (e.g. #1234). (link)

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

Lovely!

This branch has not been deployed

No deployments
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.

Flutter DevTools Performance page fails to load on nubia Pad Pro DevTools performance page broken when using systrace recorder

2 participants