Closed Bug 3262 Opened 26 years ago Closed 26 years ago

[BLOCKED-Ender] Crash in nsBlockFrame when trying to remove content

Categories

(Core :: Layout, defect, P1)

x86
Windows NT
defect

Tracking

()

VERIFIED FIXED

People

(Reporter: kostello, Assigned: buster)

Details

We found this crasher when doing an undo, although it also happens during a intermittently during a delete operation. 1) Launch Viewer 2) Go to the tools menu, select Editor Mode (IMPORTANT!) 3) Select the word "Basic" on the first line of example zero 4) Press cntl-i it should apply italic to the selection 5) Press cntl-z (crash) Looking at the stack trace, the crash always appears at the same place. The frame value is garbage. nsBlockFrame.cpp: IsEmptyLine(nsIPresContext& aPresContext, nsLineBox* aLine) { PRInt32 i, n = aLine->ChildCount(); nsIFrame* frame = aLine->mFirstChild; for (i = 0; i < n; i++) { nsIContent* content; >>> nsresult rv = frame->GetContent(&content); // CRASH HERE if (NS_FAILED(rv) || (nsnull == content)) { // If it doesn't have any content then this can't be an empty line return PR_FALSE; } [SNIP!]
Assignee: troy → kipp
Status: NEW → ASSIGNED
Assignee: kipp → kostello
Status: ASSIGNED → NEW
With the current tree, what I'm seeing is a crash in the nsRangeList.cpp file - the reason is that the range is holding onto a dead frame. I traced the malloc/frees on my system and saw a frame getting created and destroyed, yet the frame pointer in 0x402e325c in nsRangeList::TakeFocus (this=0x82a3c74, aTracker=0x82a3bb0, aFrame=0x825e3fc, aOffset=17, aContentOffset=0, aContinueSelection=0) at nsRangeList.cpp:786 786 frame->SetSelected(PR_FALSE, 0, -1, PR_FALSE);//just turn off Pointed to the recently deleted memory. I suggest you folks run this under purify on windows and work out the selection bugs first; then after it doesn't crash there, hand it back to me if it still crashes.
Assignee: kostello → jfrancis
assigned to joe, but maybe should go to mike. I'll let those two decide.
rangeList stuff is Mike's domain. I've pointed him at this bug. If he doesn't grab it soon I'll work on it.
Severity: normal → critical
bumped up severity. I see this crash with lots of editing operations, so hopefully mike or joe will look at it very soon. the more editing operations that come on line, the more this bug will impact progress.
I should also note the the stack is not always identical. There may be several related crashes, or just one that happens to have slightly different symptoms. In each case, it's dereferencing a garbage pointer to a frame that causes the crash.
Status: NEW → ASSIGNED
PresShell::ClearFrameRefs() was not clearing out mAnchorEventFrame. Fixing this seems to allow some deletions to succeed that didn't before, but there are still crashes. I'm just going to leave this bug open for the remaining deletion crashes rather than closing thiis one and opening a new one.
QA Contact: 4110 → 4144
Changing QA contact to petersen@netscape.com (Layout QA contact).
The bug can be crecreated by: 1. Starting up viewer with example 0 2. Selecting Tools->Editor Mode from the menus. 3. Making a selection from before the first '.' character to the end of the first occurrence of the word "cyan" (2 lines below the '.'). 4. Hit the backspace key. You should see a crash in IsEmptyLine(). In DoRemoveFrame(), it looks like we can get into a situation where a frame deletion can decrement the wrong line count, and not remove the deleted frame from the correct line list. This situation happens when aDeletedFrame and nextInFlow are in the same line. The current algorithm always sets line to nextLine, even if nextInFlow is in the same line. This means that during the next loop iteration, after aDeletedFrame is set to nextInFlow, the logic will be looking at the wrong line. We added some code (bracketed by KDEBUG comments) that stopped line from being set to next line. This seems to prevent the crash: else { // XXX if we just removed a place-holder frame don't bother // marking the line dirty. line->MarkDirty(); linep = &line->mNext; } //**** KDEBUG **** if (aDeletedFrame == line->mFirstChild && line->mChildCount > 0) continue; //**** KDEBUG **** prevLine = line; line = next;
Assignee: jfrancis → kipp
Status: ASSIGNED → NEW
This is a layout bug. Reassigning to kipp@netscape.com.
Target Milestone: M3
A couple of other things: Should DoRemoveFrame() call RemoveFromFlow() inststead of BreakFromNextFlow() to make sure that mPrevInFlow pointers get set properly? // Destroy frame; capture its next-in-flow first in case we need // to destroy that too. nsIFrame* nextInFlow; aDeletedFrame->GetNextInFlow(&nextInFlow); //**** KDEBUG **** // if (nsnull != nextInFlow) { // aDeletedFrame->BreakFromNextFlow(); // } aDeletedFrame->RemoveFromFlow(); //**** KDEBUG **** aDeletedFrame->DeleteFrame(aPresContext); aDeletedFrame = nextInFlow; // If line is empty, remove it now nsLineBox* next = line->mNext; if (0 == --line->mChildCount) { *linep = next; line->mNext = nsnull; delete line; //**** KDEBUG **** line = prevLine; //**** KDEBUG **** } else { // XXX if we just removed a place-holder frame don't bother // marking the line dirty. line->MarkDirty(); linep = &line->mNext; } //**** KDEBUG **** if (aDeletedFrame == line->mFirstChild && line->mChildCount > 0) continue; //**** KDEBUG **** prevLine = line; line = next; After patching my version of DoRemoveFrame(), I get farther, but then I crash in nsTextTransformer::GetNextWord() during the reflow that occurs after everything gets deleted. It crashes in this piece of code: else { const unsigned char* cp = (const unsigned char*) frag->Get1b(); firstChar = PRUnichar(cp[offset]); } because offset is something like -1140355944. I tracked it down to the fact that one of the current frame's mPrevInFlow is stale since it wasn't reset properly when it's previous frame was deleted. I patched my version of nsInlineFrame::RemoveFrame() to call RemoveFromFlow() before deleting the frame, and things work again.
Summary: Crash in nsBlockFrame when trying to remove content → [BLOCKED-Ender] Crash in nsBlockFrame when trying to remove content
Status: NEW → ASSIGNED
Status: ASSIGNED → RESOLVED
Closed: 26 years ago
Resolution: --- → FIXED
I just landed numerous fixes to the block code and a few fixes to the inline code for handling removale much better. Note that 99% of the bugs were because of "first-letter" style on the lines in test0.html...
Status: RESOLVED → REOPENED
With the March 16th Build, I still get a crash after pressing Control-Z with the "Basic" selected. I renamed the test0.html document to EditorInitPagePlain.html so that Editor would load it by default.
Are kipp's fixes in the build you're playing with? He just checked them in around noon today.
I'm using the build that was available this morning (March 16th). I guess tomorrow's build will have his changes. I would love to see it fixed.
Status: REOPENED → ASSIGNED
Status: ASSIGNED → RESOLVED
Closed: 26 years ago26 years ago
Please don't reopen a bug unless (a) you know you are running code with the purposed fixes and (b) it doesn't work. Since you didn't do (a) please leave it closed.
Status: RESOLVED → VERIFIED
Fixed in March 19th Build (M3)
You need to log in before you can comment on or make changes to this bug.