Closed Bug 1701027 Opened 4 years ago Closed 3 years ago

Using Eyedropper crash in [@ RetainedDisplayListBuilder::MergeDisplayLists]

Categories

(Core :: Web Painting, defect, P2)

Firefox 89
Desktop
All
defect

Tracking

()

RESOLVED FIXED
92 Branch
Tracking Status
firefox-esr78 --- unaffected
firefox-esr91 --- fixed
firefox86 --- wontfix
firefox87 --- wontfix
firefox88 --- wontfix
firefox89 --- wontfix
firefox90 --- wontfix
firefox91 --- wontfix
firefox92 --- fixed

People

(Reporter: alice0775, Assigned: tnikkel)

References

(Regression)

Details

(Keywords: crash, regression, reproducible)

Crash Data

Attachments

(2 files)

Crash report: https://crash-stats.mozilla.org/report/index/f5b2f9e7-1312-4c24-817c-3c0720210325

MOZ_CRASH Reason: Item found was in the wrong list! type 585 (outer type was 53 at depth 2, now is 2)

Top 10 frames of crashing thread:

0 xul.dll RetainedDisplayListBuilder::MergeDisplayLists layout/painting/RetainedDisplayListBuilder.cpp:801
1 xul.dll RetainedDisplayListBuilder::MergeDisplayLists layout/painting/RetainedDisplayListBuilder.cpp:812
2 xul.dll RetainedDisplayListBuilder::MergeDisplayLists layout/painting/RetainedDisplayListBuilder.cpp:812
3 xul.dll RetainedDisplayListBuilder::MergeDisplayLists layout/painting/RetainedDisplayListBuilder.cpp:812
4 xul.dll RetainedDisplayListBuilder::AttemptPartialUpdate layout/painting/RetainedDisplayListBuilder.cpp:1462
5 xul.dll static nsLayoutUtils::PaintFrame layout/base/nsLayoutUtils.cpp:3366
6 xul.dll mozilla::PresShell::Paint layout/base/PresShell.cpp:6391
7 xul.dll nsViewManager::ProcessPendingUpdatesPaint view/nsViewManager.cpp:459
8 xul.dll nsViewManager::ProcessPendingUpdatesForView view/nsViewManager.cpp:394
9 xul.dll nsViewManager::ProcessPendingUpdates view/nsViewManager.cpp:972

Steps to reproduce:

  1. Open about:processes or about:performance
  2. Web Developer > Eyedropper
  3. Left mouse click on the list

Actual Results:
Nightly crash

Regressed by: desktop-zoom-nightly
Has Regression Range: --- → yes

Probably mWillBuildScrollableLayer is changing in a way that nothing invalidates.

No, that's actually not the problem. We get a displayport and that invalidates. It's on the paint after we handle that invalidation that we hit the assert.

The eyedropper is implemented using top layer items. We wrap the top layer items in a display wrap list that uses the viewport frame as it's mFrame here

https://searchfox.org/mozilla-central/rev/bb37e6fe8bbe383a57a4ad21a201e26416613ca1/layout/generic/ViewportFrame.cpp#236

So when we invalidate the root scroll frame for getting a new display port we do a partial update. The wrap list item for the top layer items has a new display item parent, a display async zoom item (the creation of the display port changed this), so the a new display wrap list item is created. All of it's children are matched with the old children of the old display wrap list so those go away, but the old display wrap list item itself sticks around: it's mFrame is the viewport frame which was not marked modified. So the next paint we have these two identical display wrap list items (one empty), and we hit the assert.

So it seems like we need to mark the viewport frame modified if the root scroll frame is marked modified if we have top layer items (since those top layers items end up being inside the root scroll frames display list). This in turn would disable a partial update for the next paint because ShouldBuildPartial would return false because a viewport frame is modified

https://searchfox.org/mozilla-central/rev/bb37e6fe8bbe383a57a4ad21a201e26416613ca1/layout/painting/RetainedDisplayListBuilder.cpp#1309

I'm not sure this is even a bad thing, since we also disable partial updates if the canvas frame (child of the root scroll frame) is marked modified. Perhaps we would want to disable partial updates if the root scroll frame is marked modified, but we can't detect root scroll frames purely from their layout frame type.

This is basically equivalent to marking the viewport frame modified when the root scroll frame is marked modified.

We wrap the top layer items in a display wrap list that uses the viewport frame as it's mFrame here

https://searchfox.org/mozilla-central/rev/bb37e6fe8bbe383a57a4ad21a201e26416613ca1/layout/generic/ViewportFrame.cpp#236

So when we invalidate the root scroll frame for getting a new display port we do a partial update. The wrap list item for the top layer items has a new display item parent, a display async zoom item (the creation of the display port changed this), so the a new display wrap list item is created. All of it's children are matched with the old children of the old display wrap list so those go away, but the old display wrap list item itself sticks around: it's mFrame is the viewport frame which was not marked modified. So the next paint we have these two identical display wrap list items (one empty), and we hit the assert.

So it seems like we need to mark the viewport frame modified if the root scroll frame is marked modified if we have top layer items (since those top layers items end up being inside the root scroll frames display list). This in turn would disable a partial update for the next paint because ShouldBuildPartial would return false because a viewport frame is modified

https://searchfox.org/mozilla-central/rev/bb37e6fe8bbe383a57a4ad21a201e26416613ca1/layout/painting/RetainedDisplayListBuilder.cpp#1309

I'm not sure this is even a bad thing, since we also disable partial updates if the canvas frame (child of the root scroll frame) is marked modified. Perhaps we would want to disable partial updates if the root scroll frame is marked modified, but we can't detect root scroll frames purely from their layout frame type.

Assignee: nobody → tnikkel
Status: NEW → ASSIGNED
Severity: -- → S2
Priority: -- → P2
See Also: → 1691906
See Also: → 1664395

There's a r+ patch which didn't land and no activity in this bug for 2 weeks.
:tnikkel, could you have a look please?
For more information, please visit auto_nag documentation.

Flags: needinfo?(tnikkel)
Flags: needinfo?(matt.woodrow)

Need to write a test but I'm doing mr1 work.

Flags: needinfo?(tnikkel)
Flags: needinfo?(matt.woodrow)
OS: Windows 10 → All

If we don't have a test yet can we file a follow-up for that and land the patch so we at least stop crashing?

Flags: needinfo?(tnikkel)
Pushed by tnikkel@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/8bc7d0c76297 Disable partial display list updates when the root scroll frame is modified. r=mattwoodrow https://hg.mozilla.org/integration/autoland/rev/9b2eab0bda3d Add test. r=hiro
Flags: needinfo?(tnikkel)
Status: ASSIGNED → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → 92 Branch

Please nominate this for ESR91 approval when you get a chance.

Flags: needinfo?(tnikkel)

Comment on attachment 9211685 [details]
Bug 1701027. Disable partial display list updates when the root scroll frame is modified. r?mattwoodrow

ESR Uplift Approval Request

  • If this is not a sec:{high,crit} bug, please state case for ESR consideration: easily reproduced crash with simple fix
  • User impact if declined: crash in certain cases
  • Fix Landed on Version: 92
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): adds a simple case to skip trying to do a partial display list update
  • String or UUID changes made by this patch:
Flags: needinfo?(tnikkel)
Attachment #9211685 - Flags: approval-mozilla-esr91?
Attachment #9232295 - Flags: approval-mozilla-esr91?

Comment on attachment 9211685 [details]
Bug 1701027. Disable partial display list updates when the root scroll frame is modified. r?mattwoodrow

Approved for 91.1esr.

Attachment #9211685 - Flags: approval-mozilla-esr91? → approval-mozilla-esr91+
Attachment #9232295 - Flags: approval-mozilla-esr91? → approval-mozilla-esr91+
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: