Open Bug 1819173 Opened 1 year ago Updated 1 year ago

###!!! ASSERTION: identical: 'pseudoType1 != pseudoType2', file layout/base/nsGenConList.cpp:111

Categories

(Core :: Layout: Generated Content, Lists, and Counters, defect)

defect

Tracking

()

People

(Reporter: dholbert, Unassigned)

References

Details

(Keywords: assertion)

Ran into a lot of instances of this non-fatal assertion when trying STR for bug 1682072:

[Child 751942, Main Thread] ###!!! ASSERTION: identical: 'pseudoType1 != pseudoType2', file layout/base/nsGenConList.cpp:111

This was added in bug 1552719; adding loose dependency on that bug. (Not sure if this issue goes back that far or not.)

The STR here are just:

  1. In a debug build, load https://getpocket.com/explore/item/chris-farley-the-wild-ride-and-sad-end
  2. Print-preview.

ACTUAL RESULTS:
Lots of instances of this nonfatal assertion.

Pernosco trace, seeked to one of these assertion-failures (the first one I think):
https://pernos.co/debug/mEayZfMcirm2q05kMt5jQQ/index.html#f{m[BsGW,AA_,t[3Q,DC71_,f{e[BsGR,R31V_,s{af366YAAA,bCgQ,uEdMp1Q,oEeJOXQ___/

The assertion is here:https://searchfox.org/mozilla-central/rev/f7edb0b474a1a922f3285107620e802c6e19914d/layout/base/nsGenConList.cpp#98-101,108-111

bool nsGenConList::NodeAfter(const nsGenConNode* aNode1,
                             const nsGenConNode* aNode2) {
  nsIFrame* frame1 = aNode1->mPseudoFrame;
  nsIFrame* frame2 = aNode2->mPseudoFrame;
...
  int32_t pseudoType1 = PseudoCompareType(frame1, &content1);
  int32_t pseudoType2 = PseudoCompareType(frame2, &content2);
  if (content1 == content2) {
    NS_ASSERTION(pseudoType1 != pseudoType2, "identical");

We fail the assertion since pseudoType1 and pseudoType2 are both 0. 0 represents the "otherwise..." case in PseudoCompareType (i.e. the frame is not for ::before or ::after or ::marker; it's something else.)

Why are we "otherwise"? In fact, frame1->Style()->GetPseudoType() and frame2->Style()->GetPseudoType() are both NotPseudo.

It's a bit odd that these frames are NotPseudo, given that the frames come from aNode1->mPseudoFrame and aNode2->mPseudoFrame . But in fact it seems like this is as-expected and is just a confusing/not-quite-accurate naming convention.

These nodes are instances of nsCounterChangeNode, and the constructor there says that the aPseudoFrame doesn't have to be a frame for a pseudo-element:
https://searchfox.org/mozilla-central/rev/f7edb0b474a1a922f3285107620e802c6e19914d/layout/base/nsCounterManager.h#135-138,141,160

struct nsCounterChangeNode : public nsCounterNode {
  // |aPseudoFrame| is not necessarily a pseudo-element's frame, but
  // since it is for every other subclass of nsGenConNode, we follow
  // the naming convention here.
...
  nsCounterChangeNode(nsIFrame* aPseudoFrame, nsCounterNode::Type aChangeType,
...
    mPseudoFrame = aPseudoFrame;

(And frame1 and frame2 are instances of ColumnSetWrapperFrame, FWIW.)

So: it's ~fine for us to get here with NotPseudo frames. And I guess the code expects that, though it's confused by the fact that we have two frames that have the same content node. I think what's going on is that the two frames are continuations of each other, though? They don't seem to be linked as continuations yet, but they seem to share the same content node pointer and their ancestor chains point to different pages.

You need to log in before you can comment on or make changes to this bug.