Bug 13563

Summary: REGRESSION: Crash loading message in Yahoo! Mail
Product: WebKit Reporter: David Kilzer (:ddkilzer) <ddkilzer@webkit.org>
Component: CSSAssignee: Nobody <webkit-unassigned@lists.webkit.org>
Status: RESOLVED FIXED    
Severity: Normal CC: bdakin@apple.com, hyatt@apple.com, mitz@webkit.org
Priority: P1 Keywords: InRadar, NeedsReduction, Regression
Version: 523.x (Safari 3)   
Hardware: Macintosh   
OS: Mac OS X 10.4   
Attachments:
Description Flags
Test page (webarchive)
none
Test case (web page, complete from Firefox)
none
Debug patch
none
Reduction (will crash when you click Test)
none
Keep updating the style selector once you calculated it hyatt: review+

Description From 2007-05-01 11:34:30 PST
* SUMMARY

Crash loading a mail message in Yahoo! Mail.

* CONSOLE OUTPUT

Segmentation fault

* STACK TRACE

Exception:  EXC_BAD_ACCESS (0x0001)
Codes:      KERN_INVALID_ADDRESS (0x0001) at 0x4082600c

Thread 0 Crashed:
0   com.apple.WebCore            0x0158fbfc WTF::RefPtr<WebCore::StringImpl>::get() const + 20 (RefPtr.h:45)
1   com.apple.WebCore            0x0158fc34 WebCore::String::impl() const + 36 (PlatformString.h:151)
2   com.apple.WebCore            0x01594ba0 WebCore::AtomicString::impl() const + 36 (AtomicString.h:50)
3   com.apple.WebCore            0x01594c2c WebCore::operator==(WebCore::AtomicString const&, WebCore::AtomicString const&) + 48 (AtomicString.h:103)
4   com.apple.WebCore            0x0114fab0 WebCore::CSSStyleSelector::matchRulesForList(WebCore::CSSRuleDataList*, int&, int&) + 188 (cssstyleselector.cpp:432)
5   com.apple.WebCore            0x0114fd28 WebCore::CSSStyleSelector::matchRules(WebCore::CSSRuleSet*, int&, int&) + 176 (cssstyleselector.cpp:396)
6   com.apple.WebCore            0x0115efe0 WebCore::CSSStyleSelector::styleForElement(WebCore::Element*, WebCore::RenderStyle*, bool, bool) + 1212 (cssstyleselector.cpp:867)
7   com.apple.WebCore            0x012b893c WebCore::Element::recalcStyle(WebCore::Node::StyleChange) + 484 (Element.cpp:675)
8   com.apple.WebCore            0x012b8c80 WebCore::Element::recalcStyle(WebCore::Node::StyleChange) + 1320 (Element.cpp:713)
9   com.apple.WebCore            0x012b8c80 WebCore::Element::recalcStyle(WebCore::Node::StyleChange) + 1320 (Element.cpp:713)
10  com.apple.WebCore            0x012b8c80 WebCore::Element::recalcStyle(WebCore::Node::StyleChange) + 1320 (Element.cpp:713)
11  com.apple.WebCore            0x012b8c80 WebCore::Element::recalcStyle(WebCore::Node::StyleChange) + 1320 (Element.cpp:713)
12  com.apple.WebCore            0x012b8c80 WebCore::Element::recalcStyle(WebCore::Node::StyleChange) + 1320 (Element.cpp:713)
13  com.apple.WebCore            0x012b8c80 WebCore::Element::recalcStyle(WebCore::Node::StyleChange) + 1320 (Element.cpp:713)
14  com.apple.WebCore            0x0110048c WebCore::Document::recalcStyle(WebCore::Node::StyleChange) + 1284 (Document.cpp:1024)
15  com.apple.WebCore            0x010f67f4 WebCore::Document::updateRendering() + 84 (Document.cpp:1049)
16  com.apple.WebCore            0x012eadbc KJS::ScheduledAction::execute(KJS::Window*) + 1168 (kjs_window.cpp:1940)
17  com.apple.WebCore            0x012edec4 KJS::Window::timerFired(KJS::DOMWindowTimer*) + 504 (kjs_window.cpp:2054)
18  com.apple.WebCore            0x012edf60 KJS::DOMWindowTimer::fired() + 72 (kjs_window.cpp:2640)
19  com.apple.WebCore            0x0126a88c WebCore::TimerBase::fireTimers(double, WTF::Vector<WebCore::TimerBase*, (unsigned long)0> const&) + 240 (Timer.cpp:322)
20  com.apple.WebCore            0x0126a958 WebCore::TimerBase::sharedTimerFired() + 132 (Timer.cpp:355)
21  com.apple.WebCore            0x01269d48 WebCore::timerFired(__CFRunLoopTimer*, void*) + 60 (SharedTimerMac.cpp:47)
22  com.apple.CoreFoundation     0x907f2578 __CFRunLoopDoTimer + 184
23  com.apple.CoreFoundation     0x907deef8 __CFRunLoopRun + 1680
24  com.apple.CoreFoundation     0x907de4ac CFRunLoopRunSpecific + 268
25  com.apple.HIToolbox          0x93298b20 RunCurrentEventLoopInMode + 264
26  com.apple.HIToolbox          0x932981b4 ReceiveNextEventCommon + 380
27  com.apple.HIToolbox          0x93298020 BlockUntilNextEventMatchingListInMode + 96
28  com.apple.AppKit             0x9379eae4 _DPSNextEvent + 384
29  com.apple.AppKit             0x9379e7a8 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 116
30  com.apple.Safari             0x00006740 0x1000 + 22336
31  com.apple.AppKit             0x9379acec -[NSApplication run] + 472
32  com.apple.AppKit             0x9388b87c NSApplicationMain + 452
33  com.apple.Safari             0x0005c77c 0x1000 + 374652
34  com.apple.Safari             0x0005c624 0x1000 + 374308
------- Comment #1 From 2007-05-01 14:27:06 PST -------
Reproduced with a local debug build of WebKit r21200 with Safari 2.0.4 (419.3) on Mac OS X 10.4.9 (8P135).

Note that this doesn't reproduce every time...I've had to reload a few times before the bug has occurred.  (And of course I can't reproduce it at all now.)
------- Comment #2 From 2007-05-01 14:27:56 PST -------
Created an attachment (id=14301) [details]
Test page (webarchive)

Please, no smart-aleck comments about the contents of the message. :)
------- Comment #3 From 2007-05-01 14:29:05 PST -------
Created an attachment (id=14302) [details]
Test case (web page, complete from Firefox)

Note that I have NOT been able to reproduce the bug loading this page or the webarchive.
------- Comment #4 From 2007-05-01 14:45:57 PST -------
Slightly different stack trace:

Exception:  EXC_BAD_ACCESS (0x0001)
Codes:      KERN_PROTECTION_FAILURE (0x0002) at 0x00000070

Thread 0 Crashed:
0   com.apple.WebCore                  0x0114fb54 WebCore::CSSStyleSelector::matchRulesForList(WebCore::CSSRuleDataList*, int&, int&) + 352 (cssstyleselector.cpp:435)
1   com.apple.WebCore                  0x0114fd28 WebCore::CSSStyleSelector::matchRules(WebCore::CSSRuleSet*, int&, int&) + 176 (cssstyleselector.cpp:396)
2   com.apple.WebCore                  0x0115efe0 WebCore::CSSStyleSelector::styleForElement(WebCore::Element*, WebCore::RenderStyle*, bool, bool) + 1212 (cssstyleselector.cpp:867)
3   com.apple.WebCore                  0x012b893c WebCore::Element::recalcStyle(WebCore::Node::StyleChange) + 484 (Element.cpp:675)
4   com.apple.WebCore                  0x012b8c80 WebCore::Element::recalcStyle(WebCore::Node::StyleChange) + 1320 (Element.cpp:713)
5   com.apple.WebCore                  0x012b8c80 WebCore::Element::recalcStyle(WebCore::Node::StyleChange) + 1320 (Element.cpp:713)
6   com.apple.WebCore                  0x012b8c80 WebCore::Element::recalcStyle(WebCore::Node::StyleChange) + 1320 (Element.cpp:713)
7   com.apple.WebCore                  0x012b8c80 WebCore::Element::recalcStyle(WebCore::Node::StyleChange) + 1320 (Element.cpp:713)
8   com.apple.WebCore                  0x012b8c80 WebCore::Element::recalcStyle(WebCore::Node::StyleChange) + 1320 (Element.cpp:713)
9   com.apple.WebCore                  0x012b8c80 WebCore::Element::recalcStyle(WebCore::Node::StyleChange) + 1320 (Element.cpp:713)
10  com.apple.WebCore                  0x0110048c WebCore::Document::recalcStyle(WebCore::Node::StyleChange) + 1284 (Document.cpp:1024)
11  com.apple.WebCore                  0x010f67f4 WebCore::Document::updateRendering() + 84 (Document.cpp:1049)
12  com.apple.WebCore                  0x012eadbc KJS::ScheduledAction::execute(KJS::Window*) + 1168 (kjs_window.cpp:1940)
13  com.apple.WebCore                  0x012edec4 KJS::Window::timerFired(KJS::DOMWindowTimer*) + 504 (kjs_window.cpp:2054)
14  com.apple.WebCore                  0x012edf60 KJS::DOMWindowTimer::fired() + 72 (kjs_window.cpp:2640)
15  com.apple.WebCore                  0x0126a88c WebCore::TimerBase::fireTimers(double, WTF::Vector<WebCore::TimerBase*, (unsigned long)0> const&) + 240 (Timer.cpp:322)
16  com.apple.WebCore                  0x0126a958 WebCore::TimerBase::sharedTimerFired() + 132 (Timer.cpp:355)
17  com.apple.WebCore                  0x01269d48 WebCore::timerFired(__CFRunLoopTimer*, void*) + 60 (SharedTimerMac.cpp:47)
18  com.apple.CoreFoundation           0x907f2578 __CFRunLoopDoTimer + 184
19  com.apple.CoreFoundation           0x907deef8 __CFRunLoopRun + 1680
20  com.apple.CoreFoundation           0x907de4ac CFRunLoopRunSpecific + 268
21  com.apple.HIToolbox                0x93298b20 RunCurrentEventLoopInMode + 264
22  com.apple.HIToolbox                0x932981b4 ReceiveNextEventCommon + 380
23  com.apple.HIToolbox                0x93298020 BlockUntilNextEventMatchingListInMode + 96
24  com.apple.AppKit                   0x9379eae4 _DPSNextEvent + 384
25  com.apple.AppKit                   0x9379e7a8 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 116
26  com.apple.Safari                   0x00006740 0x1000 + 22336
27  com.apple.AppKit                   0x9379acec -[NSApplication run] + 472
28  com.apple.AppKit                   0x9388b87c NSApplicationMain + 452
29  com.apple.Safari                   0x0005c77c 0x1000 + 374652
30  com.apple.Safari                   0x0005c624 0x1000 + 374308
------- Comment #5 From 2007-05-01 14:48:41 PST -------
NOTE: The content may have to be served from a web server (to get the timing right) to reproduce.

Also, I noticed clearing the browser cache (Cmd-Opt-E) helps to reproduce the issue.

I still have not been able to reproduce using either the Firefox web-page-complete copy or the webarchvie.
------- Comment #6 From 2007-05-01 19:42:12 PST -------
What appears to be happening is that the loop iterating over CSSRuleData objects in CSSStyleSelector::matchRulesForList() is getting a rule that has been deleted (or is in the process of being deleted) while it's being accessed in that loop.
------- Comment #7 From 2007-05-02 01:16:35 PST -------
Opening the archive just redirects to Yahoo login page in my case.
------- Comment #8 From 2007-05-03 09:45:16 PST -------
Using this interesting hack:

 StringImpl::~StringImpl()
 {
+fprintf(stderr, ">>> StringImpl::~StringImpl() %p '%s'\n", this, ascii().data());
     if (m_inTable)
         AtomicString::remove(this);
     deleteUCharVector(m_data);
 }

I discovered that this interesting bit of JavaScript from function rmvScroll(msg) in the body of the main page was being run during page layout:

if ( newWidth > 0 || newHeight > 0 ) {
    var ssxyzzy = document.getElementById( "ssxyzzy" );
    var cssAttribs = ['#message {'];
    if ( newWidth > 0 ) cssAttribs.push( 'width:' + newWidth + 'px;' );
    if ( newHeight > 0 ) cssAttribs.push( ' height:' + newHeight + 'px;' );
    cssAttribs.push( '}' );
    try {
        ssxyzzy.sheet.deleteRule( 0 );  // DURING LAYOUT!
        ssxyzzy.sheet.insertRule( cssAttribs.join(""), 0 );
    } catch( e ){}
}

It would appear that the CSS rules are being deleted by JavaScript during layout!  It's not good to be deleting rules from stylesheets when you're running CSSStyleSelector::matchRulesForList() in cssstyleselector.cpp.

Haven't had time to figure out how to create a reproducible test case (or a fix), but the problem is quite obvious now.
------- Comment #9 From 2007-05-03 14:49:29 PST -------
Executing arbitrary JS under layout is bad for you. It's probably event dispatch that should go through FrameView::scheduleEvent. A call stack from when it happens would help.
------- Comment #10 From 2007-05-03 15:09:15 PST -------
(In reply to comment #8)
> Haven't had time to figure out how to create a reproducible test case (or a
> fix), but the problem is quite obvious now.

Actually, it's not.  I'll should really stop using my "Jump to Conclusions" mat.  Will try to create a reproducible test case.
------- Comment #11 From 2007-05-03 19:49:23 PST -------
The webarchive didn't work (tried to load up Yahoo), and the static page didn't crash for me.
------- Comment #12 From 2007-05-04 22:19:41 PST -------
<rdar://problem/5183694>
------- Comment #13 From 2007-05-15 16:22:45 PST -------
(In reply to comment #6)
> What appears to be happening is that the loop iterating over CSSRuleData
> objects in CSSStyleSelector::matchRulesForList() is getting a rule that has
> been deleted (or is in the process of being deleted) while it's being accessed
> in that loop.

If the bug is still reproducible, could you do the following? Set a breakpoint at ~CSSRuleData() and have it print |this| and a backtrace each time it's hit. When you crash as a result of dereferencing a deleted CSSRuleData, get the invalid pointer and find the backtrace from when it was deleted. Not sure it would help much, but IMO it's worth trying.
------- Comment #14 From 2007-05-15 22:55:35 PST -------
(In reply to comment #13)
> If the bug is still reproducible, could you do the following? Set a breakpoint
> at ~CSSRuleData() and have it print |this| and a backtrace each time it's hit.
> When you crash as a result of dereferencing a deleted CSSRuleData, get the
> invalid pointer and find the backtrace from when it was deleted. Not sure it
> would help much, but IMO it's worth trying.

Oh yes, it's still reproducible.  If you want me to forward a message to your own Yahoo! Mail account, let me know.

I understand the technique you're using to find who deleted the CSSRuleData, but I'm going to have to do learn more about gdb before I can do that.
------- Comment #15 From 2007-05-15 23:37:58 PST -------
(In reply to comment #14)
> I understand the technique you're using to find who deleted the CSSRuleData,
> but I'm going to have to do learn more about gdb before I can do that.

Okay, figured this out.  Now I have to wait for the page to load and the spew to stop!
------- Comment #16 From 2007-05-16 14:36:55 PST -------
(In reply to comment #13)
> If the bug is still reproducible, could you do the following? Set a breakpoint
> at ~CSSRuleData() and have it print |this| and a backtrace each time it's hit.
> When you crash as a result of dereferencing a deleted CSSRuleData, get the
> invalid pointer and find the backtrace from when it was deleted. Not sure it
> would help much, but IMO it's worth trying.

I don't believe it's the CSSRuleData or CSSStyleRule that's being deleted.  Still researching.
------- Comment #17 From 2007-05-16 18:01:23 PST -------
(In reply to comment #16)
> I don't believe it's the CSSRuleData or CSSStyleRule that's being deleted. 

This is very much timing-related, so slowing down the browser with gdb backtraces or big fprintf() statements makes it harder to reproduce.  :(
------- Comment #18 From 2007-05-16 22:13:49 PST -------
Taking a slightly different approach, let's look at where a method named "deleteRule()" is implemented:

void CSSMediaRule::deleteRule(unsigned index, ExceptionCode& ec)
void CSSRuleList::deleteRule(unsigned index)
void CSSStyleSheet::deleteRule(unsigned index, ExceptionCode& ec)

If we look at CSSMediaRule::deleteRule(), we see it calls CSSRuleList::deleteRule().  However, CSSStyleSheet::deleteRule() seems to be an island unto itself.

I'm not sure how these are all supposed to be connected, but I think this is the source of this issue.

Still investigating (until someone else confirms this).
------- Comment #19 From 2007-05-16 23:31:12 PST -------
Okay, I've been doing too much guessing.

By adding specific debugging output, I can confirm that:

- the rmvScroll(msg) JavaScript function on the page fires
- which calls ssxyzzy.sheet.deleteRule(0)
- which deletes a CSSStyleRule object
- which deletes a CSSSelector
- which then causes deleted pointers to be accessed through CSSStyleSelector::matchRulesForList()
- which causes a crash.

The timing of when ssxyzzy.sheet.deleteRule(0) is critical.  Most times when the page loads, it happens to "early".  It's only when the rmvScroll(msg) JavaScript function fires many times that the crash is likely to occur.

Still investigating.
------- Comment #20 From 2007-05-17 00:17:37 PST -------
Created an attachment (id=14588) [details]
Debug patch

This is the patch I used to determine what's happening when this bug is triggered.

Basically, the bug occurs when:

1. The rmvScroll(msg) JavaScript method fires.

2. Before rmvScroll(msg) calls deleteRule(), its code triggers a partial relayout.  If I had to guess, it would be one of these two lines:

    msg.style.overflow = "visible";
    msg.style.visibility = "visible";

3. The deleteRule() and InsertRule() methods are called, replacing the rules.

4. The relayout continues after the stylesheet change, except that some data structures still have references to deleted objects causing the crash.

The backtrace when deleteRule() is called from rmvScroll(msg) when the bug happens (and when it doesn't) looks like this:

Breakpoint 1, WebCore::CSSSelector::~CSSSelector () at CSSSelector.h:65
65      fprintf(stderr, "Deleting CSSSelector(%s) = %p\n", selectorText().ascii().data(), this);
#0  WebCore::CSSSelector::~CSSSelector () at CSSSelector.h:65
#1  0x01671f10 in WebCore::CSSSelector::~CSSSelector (this=0x170313d0) at CSSSelector.h:69
#2  0x0134b7b8 in WebCore::CSSStyleRule::~CSSStyleRule () at /Volumes/Data/WebKit/WebCore/css/CSSStyleRule.cpp:47
#3  0x015a4acc in WebCore::Shared<WebCore::StyleBase>::deref (this=0x17031434) at Shared.h:52
#4  0x0167205c in WTF::RefPtr<WebCore::StyleBase>::~RefPtr () at RefPtr.h:41
#5  0x01672090 in WTF::RefPtr<WebCore::StyleBase>::~RefPtr (this=0x1733b120) at RefPtr.h:41
#6  0x017412e4 in WTF::Vector<WTF::RefPtr<WebCore::StyleBase>, 0ul>::remove (this=0x173260d4, position=0) at Vector.h:702
#7  0x01354ce0 in WebCore::StyleList::remove (this=0x173260c0, position=0) at /Volumes/Data/WebKit/WebCore/css/StyleList.cpp:51
#8  0x013472d8 in WebCore::CSSStyleSheet::deleteRule (this=0x173260c0, index=0, ec=@0xbfffd870) at /Volumes/Data/WebKit/WebCore/css/CSSStyleSheet.cpp:118
#9  0x012c8f50 in KJS::DOMCSSStyleSheetPrototypeFunction::callAsFunction (this=0x17231480, exec=0xbfffde2c, thisObj=0x17231440, args=@0xbfffd958) at /Volumes/Data/WebKit/WebCore/bindings/js/kjs_css.cpp:635
#10 0x0059b4f8 in KJS::JSObject::call (this=0x17231480, exec=0xbfffde2c, thisObj=0x17231440, args=@0xbfffd958) at object.cpp:98
#11 0x005c083c in KJS::FunctionCallDotNode::evaluate (this=0x1702baa0, exec=0xbfffde2c) at nodes.cpp:790
#12 0x005bceb8 in KJS::ExprStatementNode::execute (this=0x1702bac0, exec=0xbfffde2c) at nodes.cpp:1723
#13 0x005b96a8 in KJS::SourceElementsNode::execute (this=0x1702bae0, exec=0xbfffde2c) at nodes.cpp:2522
#14 0x005894d4 in KJS::BlockNode::execute (this=0x177f3a90, exec=0xbfffde2c) at nodes.cpp:1699
#15 0x00597ec0 in KJS::TryNode::execute (this=0x177f3ad0, exec=0xbfffde2c) at nodes.cpp:2344
#16 0x005b97fc in KJS::SourceElementsNode::execute (this=0x175b3dc0, exec=0xbfffde2c) at nodes.cpp:2528
#17 0x005894d4 in KJS::BlockNode::execute (this=0x177f3b10, exec=0xbfffde2c) at nodes.cpp:1699
#18 0x005bcd40 in KJS::IfNode::execute (this=0x177f3b30, exec=0xbfffde2c) at nodes.cpp:1742
#19 0x005b97fc in KJS::SourceElementsNode::execute (this=0x177b6f60, exec=0xbfffde2c) at nodes.cpp:2528
#20 0x005894d4 in KJS::BlockNode::execute (this=0x177f3b70, exec=0xbfffde2c) at nodes.cpp:1699
#21 0x00589624 in KJS::DeclaredFunctionImp::execute (this=0x16fffbe0, exec=0xbfffde2c) at function.cpp:317
#22 0x00598ac8 in KJS::FunctionImp::callAsFunction (this=0x16fffbe0, exec=0xbfffe18c, thisObj=0x16f5fdc0, args=@0xbfffdf70) at function.cpp:104
#23 0x0059b4f8 in KJS::JSObject::call (this=0x16fffbe0, exec=0xbfffe18c, thisObj=0x16f5fdc0, args=@0xbfffdf70) at object.cpp:98
#24 0x005c1088 in KJS::FunctionCallResolveNode::evaluate (this=0x17596d60, exec=0xbfffe18c) at nodes.cpp:694
#25 0x005bceb8 in KJS::ExprStatementNode::execute (this=0x177b6ff0, exec=0xbfffe18c) at nodes.cpp:1723
#26 0x005b96a8 in KJS::SourceElementsNode::execute (this=0x177b7010, exec=0xbfffe18c) at nodes.cpp:2522
#27 0x005894d4 in KJS::BlockNode::execute (this=0x177b7030, exec=0xbfffe18c) at nodes.cpp:1699
#28 0x00589624 in KJS::DeclaredFunctionImp::execute (this=0x16ffd2c0, exec=0xbfffe18c) at function.cpp:317
#29 0x00598ac8 in KJS::FunctionImp::callAsFunction (this=0x16ffd2c0, exec=0x1752feec, thisObj=0x16f5fdc0, args=@0x17021f24) at function.cpp:104
#30 0x0059b4f8 in KJS::JSObject::call (this=0x16ffd2c0, exec=0x1752feec, thisObj=0x16f5fdc0, args=@0x17021f24) at object.cpp:98
#31 0x012ec3cc in KJS::ScheduledAction::execute (this=0x17021f20, window=0x16f5fdc0) at /Volumes/Data/WebKit/WebCore/bindings/js/kjs_window.cpp:1918
#32 0x012ef734 in KJS::Window::timerFired (this=0x16f5fdc0, timer=0x16e79e30) at /Volumes/Data/WebKit/WebCore/bindings/js/kjs_window.cpp:2054
#33 0x012ef7d0 in KJS::DOMWindowTimer::fired (this=0x16e79e30) at /Volumes/Data/WebKit/WebCore/bindings/js/kjs_window.cpp:2641
#34 0x0126b6dc in WebCore::TimerBase::fireTimers (fireTime=1179384417.077419, firingTimers=@0xbfffe480) at /Volumes/Data/WebKit/WebCore/platform/Timer.cpp:336
#35 0x0126b7a8 in WebCore::TimerBase::sharedTimerFired () at /Volumes/Data/WebKit/WebCore/platform/Timer.cpp:353
#36 0x0126ab98 in timerFired () at /Volumes/Data/WebKit/WebCore/platform/mac/SharedTimerMac.cpp:46
#37 0x907f2578 in __CFRunLoopDoTimer ()
#38 0x907deef8 in __CFRunLoopRun ()
#39 0x907de4ac in CFRunLoopRunSpecific ()
#40 0x93298b20 in RunCurrentEventLoopInMode ()
#41 0x932981b4 in ReceiveNextEventCommon ()
#42 0x93298020 in BlockUntilNextEventMatchingListInMode ()
#43 0x9379eae4 in _DPSNextEvent ()
#44 0x9379e7a8 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#45 0x00006740 in ?? ()
#46 0x9379acec in -[NSApplication run] ()
#47 0x9388b87c in NSApplicationMain ()
#48 0x0005c77c in ?? ()
#49 0x0005c624 in ?? ()

The page load when the bug occurs looks like this (with the debug patch applied):

>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x173ebc20 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16ed0680 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x173ebc20 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16ed0680 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17332250 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16ef0eb0 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17332250 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16ef0eb0 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17767070 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x15c615e0 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17767070 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x15c615e0 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
(timer firing): function () 
{
  rmvScroll(msg);
}
(timer firing): function () 
{
  rmvScroll(msg);
}
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x1792f740 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x1734ff60 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x1792f740 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x1734ff60 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x177badd0 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17317180 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x177badd0 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17317180 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x1704f100 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x175b8be0 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x1704f100 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x175b8be0 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17731ff0 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16eeef70 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17731ff0 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16eeef70 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x1792de00 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16e7dba0 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x1792de00 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16e7dba0 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16ea9490 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16e92cc0 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16ea9490 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16e92cc0 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x1790d830 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x177eb2f0 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x1790d830 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x177eb2f0 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x175861d0 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x175ee8f0 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x175861d0 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x175ee8f0 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x173e57b0 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x175c4250 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x173e57b0 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x175c4250 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17746ae0 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16ef7d60 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17746ae0 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16ef7d60 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleSheet::deleteRule(index = 0d, ec = 0)
>>> Deleting CSSStyleRule(#message) = 0x17031430
Deleting CSSSelector(#message) = 0x170313d0
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17746ae0 CSSSelector* d->selector() = 0x170cb160 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16ef7d60 CSSSelector* d->selector() = 0x1708d010 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'

Note that when the bug does NOT occur, there is no relayout between the time that rmvScroll(msg) is called and when the deleteRule()/insertRule() code is called.  Also note that there are much fewer relayouts:

>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x173587c0 CSSSelector* d->selector() = 0x17017490 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16e93780 CSSSelector* d->selector() = 0x17569b50 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x173587c0 CSSSelector* d->selector() = 0x17017490 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16e93780 CSSSelector* d->selector() = 0x17569b50 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17044a90 CSSSelector* d->selector() = 0x17017490 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17353420 CSSSelector* d->selector() = 0x17569b50 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17044a90 CSSSelector* d->selector() = 0x17017490 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17353420 CSSSelector* d->selector() = 0x17569b50 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
(timer firing): function () 
{
  rmvScroll(msg);
}
(timer firing): function () 
{
  rmvScroll(msg);
}
>>> CSSStyleSheet::deleteRule(index = 0d, ec = 0)
>>> Deleting CSSStyleRule(#message) = 0x1702d680
Deleting CSSSelector(#message) = 0x1702d810
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x170592f0 CSSSelector* d->selector() = 0x17017490 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x1750c470 CSSSelector* d->selector() = 0x17569b50 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x170592f0 CSSSelector* d->selector() = 0x17017490 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x1750c470 CSSSelector* d->selector() = 0x17569b50 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x175da4d0 CSSSelector* d->selector() = 0x17017490 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17026b90 CSSSelector* d->selector() = 0x17569b50 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x175da4d0 CSSSelector* d->selector() = 0x17017490 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x17026b90 CSSSelector* d->selector() = 0x17569b50 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16e7a230 CSSSelector* d->selector() = 0x17017490 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x170051d0 CSSSelector* d->selector() = 0x17569b50 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x16e7a230 CSSSelector* d->selector() = 0x17017490 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'
>>> CSSStyleRule = 'div#message' CSSRuleData* d = 0x170051d0 CSSSelector* d->selector() = 0x17569b50 QualifiedName d->selector()->m_tag = 'div' AtomicString d->selector()->m_tag.localName() = 'div'

*NOTE: I am assuming a "relayout" occurs each time CSSStyleSelector::matchRulesForList() is being called, although I haven't looked at a backtrace for those functions when they're being called.
------- Comment #21 From 2007-05-17 00:49:37 PST -------
(In reply to comment #20)
> Created an attachment (id=14588) [edit] [details]
> Debug patch
> 
> This is the patch I used to determine what's happening when this bug is
> triggered.
> 
> Basically, the bug occurs when:
> 
> 1. The rmvScroll(msg) JavaScript method fires.
> 
> 2. Before rmvScroll(msg) calls deleteRule(), its code triggers a partial
> relayout.  If I had to guess, it would be one of these two lines:
> 
>     msg.style.overflow = "visible";
>     msg.style.visibility = "visible";

WRONG.  The relayouts occurs with the following JavaScript (although I don't know why this happens sometimes when loading the page and not others):

msg.clientHeight
msg.scrollHeight
msg.offsetWidth
msg.clientWidth
msg.scrollWidth


> 3. The deleteRule() and InsertRule() methods are called, replacing the rules.
> 
> 4. The relayout continues after the stylesheet change, except that some data
> structures still have references to deleted objects causing the crash.

The layouts that occur after the rule has been deleted and added are triggered by KJS::ScheduledAction::execute() in WebCore/bindings/js/kjs_window.cpp:1940 with this big, smelly comment:

    // Update our document's rendering following the execution of the timeout callback.
    // FIXME: Why not use updateDocumentsRendering to update rendering of all documents?
    // FIXME: Is this really the right point to do the update? We need a place that works
    // for all possible entry points that might possibly execute script, but this seems
    // to be a bit too low-level.
    if (Document* doc = frame->document())
        doc->updateRendering();

> *NOTE: I am assuming a "relayout" occurs each time
> CSSStyleSelector::matchRulesForList() is being called, although I haven't
> looked at a backtrace for those functions when they're being called.

This appears to be a valid assumption based on backtraces taken when the bug occurred.

Backtrace from accessing "msg.clientHeight":

Breakpoint 4, WebCore::CSSStyleSelector::matchRulesForList (this=0x187f1e40, rules=0x19559bb0, firstRuleIndex=@0xbfffd2dc, lastRuleIndex=@0xbfffd2e0) at /Volumes/Data/WebKit/WebCore/css/cssstyleselector.cpp:435
435     fprintf(stderr, ">>> CSSStyleRule = '%s' ", rule->selectorText().ascii().data());
#0  WebCore::CSSStyleSelector::matchRulesForList (this=0x187f1e40, rules=0x19559bb0, firstRuleIndex=@0xbfffd2dc, lastRuleIndex=@0xbfffd2e0) at /Volumes/Data/WebKit/WebCore/css/cssstyleselector.cpp:435
#1  0x0114fc9c in WebCore::CSSStyleSelector::matchRules (this=0x187f1e40, rules=0x18f28610, firstRuleIndex=@0xbfffd2dc, lastRuleIndex=@0xbfffd2e0) at /Volumes/Data/WebKit/WebCore/css/cssstyleselector.cpp:395
#2  0x0115ef54 in WebCore::CSSStyleSelector::styleForElement (this=0x187f1e40, e=0x189854e0, defaultParent=0x0, allowSharing=true, resolveForRootDefault=false) at /Volumes/Data/WebKit/WebCore/css/cssstyleselector.cpp:877
#3  0x012b9844 in WebCore::Element::recalcStyle (this=0x189854e0, change=WebCore::Node::Force) at /Volumes/Data/WebKit/WebCore/dom/Element.cpp:676
#4  0x012b9bc4 in WebCore::Element::recalcStyle (this=0x1878e5d0, change=WebCore::Node::Force) at /Volumes/Data/WebKit/WebCore/dom/Element.cpp:716
#5  0x012b9bc4 in WebCore::Element::recalcStyle (this=0x1893c670, change=WebCore::Node::Force) at /Volumes/Data/WebKit/WebCore/dom/Element.cpp:716
#6  0x012b9bc4 in WebCore::Element::recalcStyle (this=0x1893c730, change=WebCore::Node::Force) at /Volumes/Data/WebKit/WebCore/dom/Element.cpp:716
#7  0x012b9bc4 in WebCore::Element::recalcStyle (this=0x195bd150, change=WebCore::Node::Force) at /Volumes/Data/WebKit/WebCore/dom/Element.cpp:716
#8  0x012b9bc4 in WebCore::Element::recalcStyle (this=0x1976b6a0, change=WebCore::Node::Force) at /Volumes/Data/WebKit/WebCore/dom/Element.cpp:716
#9  0x012b9bc4 in WebCore::Element::recalcStyle (this=0x1873c400, change=WebCore::Node::Force) at /Volumes/Data/WebKit/WebCore/dom/Element.cpp:716
#10 0x01100184 in WebCore::Document::recalcStyle (this=0x2bcb600, change=WebCore::Node::Force) at /Volumes/Data/WebKit/WebCore/dom/Document.cpp:1006
#11 0x01105f8c in WebCore::Document::updateStyleSelector (this=0x2bcb600) at /Volumes/Data/WebKit/WebCore/dom/Document.cpp:1931
#12 0x0110661c in WebCore::Document::updateLayoutIgnorePendingStylesheets (this=0x2bcb600) at /Volumes/Data/WebKit/WebCore/dom/Document.cpp:1076
#13 0x012b8b78 in WebCore::Element::clientHeight (this=0x189854e0) at /Volumes/Data/WebKit/WebCore/dom/Element.cpp:334
#14 0x012a68cc in WebCore::JSElement::getValueProperty (this=0x1881fc00, exec=0xbfffde2c, token=10) at /symroots/Debug/DerivedSources/WebCore/JSElement.cpp:217
#15 0x016e4eac in KJS::staticValueGetter<WebCore::JSElement> (exec=0xbfffde2c, slot=@0xbfffda08) at lookup.h:149
#16 0x005e9820 in KJS::PropertySlot::getValue (this=0xbfffda08, exec=0xbfffde2c, originalObject=0x1881fc00, propertyName=@0x17033a4c) at property_slot.h:47
#17 0x0056e018 in KJS::JSObject::get (this=0x1881fc00, exec=0xbfffde2c, propertyName=@0x17033a4c) at object.cpp:166
#18 0x005c1730 in KJS::DotAccessorNode::evaluate (this=0x17033a40, exec=0xbfffde2c) at nodes.cpp:563
#19 0x005be790 in KJS::AddNode::evaluate (this=0x189b6ed0, exec=0xbfffde2c) at nodes.cpp:1209
#20 0x0057c8d4 in KJS::AssignExprNode::evaluate (this=0x17033ab0, exec=0xbfffde2c) at nodes.cpp:1578
#21 0x005bd44c in KJS::VarDeclNode::evaluate (this=0x195c2550, exec=0xbfffde2c) at nodes.cpp:1596
#22 0x005bd2f4 in KJS::VarDeclListNode::evaluate (this=0x16e8d370, exec=0xbfffde2c) at nodes.cpp:1643
#23 0x005bd088 in KJS::VarStatementNode::execute (this=0x195c2570, exec=0xbfffde2c) at nodes.cpp:1667
#24 0x005b97fc in KJS::SourceElementsNode::execute (this=0x195c2330, exec=0xbfffde2c) at nodes.cpp:2528
#25 0x005894d4 in KJS::BlockNode::execute (this=0x170d6c50, exec=0xbfffde2c) at nodes.cpp:1699
#26 0x00589624 in KJS::DeclaredFunctionImp::execute (this=0x1881fcc0, exec=0xbfffde2c) at function.cpp:317
#27 0x00598ac8 in KJS::FunctionImp::callAsFunction (this=0x1881fcc0, exec=0xbfffe18c, thisObj=0x16f9fdc0, args=@0xbfffdf70) at function.cpp:104
#28 0x0059b4f8 in KJS::JSObject::call (this=0x1881fcc0, exec=0xbfffe18c, thisObj=0x16f9fdc0, args=@0xbfffdf70) at object.cpp:98
#29 0x005c1088 in KJS::FunctionCallResolveNode::evaluate (this=0x16e91130, exec=0xbfffe18c) at nodes.cpp:694
#30 0x005bceb8 in KJS::ExprStatementNode::execute (this=0x195c23c0, exec=0xbfffe18c) at nodes.cpp:1723
#31 0x005b96a8 in KJS::SourceElementsNode::execute (this=0x195c23e0, exec=0xbfffe18c) at nodes.cpp:2522
#32 0x005894d4 in KJS::BlockNode::execute (this=0x195c2400, exec=0xbfffe18c) at nodes.cpp:1699
#33 0x00589624 in KJS::DeclaredFunctionImp::execute (this=0x1881d320, exec=0xbfffe18c) at function.cpp:317
#34 0x00598ac8 in KJS::FunctionImp::callAsFunction (this=0x1881d320, exec=0x187262cc, thisObj=0x16f9fdc0, args=@0x189f1f24) at function.cpp:104
#35 0x0059b4f8 in KJS::JSObject::call (this=0x1881d320, exec=0x187262cc, thisObj=0x16f9fdc0, args=@0x189f1f24) at object.cpp:98
#36 0x012ec3cc in KJS::ScheduledAction::execute (this=0x189f1f20, window=0x16f9fdc0) at /Volumes/Data/WebKit/WebCore/bindings/js/kjs_window.cpp:1918
#37 0x012ef734 in KJS::Window::timerFired (this=0x16f9fdc0, timer=0x1894ae10) at /Volumes/Data/WebKit/WebCore/bindings/js/kjs_window.cpp:2054
#38 0x012ef7d0 in KJS::DOMWindowTimer::fired (this=0x1894ae10) at /Volumes/Data/WebKit/WebCore/bindings/js/kjs_window.cpp:2641
#39 0x0126b6dc in WebCore::TimerBase::fireTimers (fireTime=1179386457.14042, firingTimers=@0xbfffe480) at /Volumes/Data/WebKit/WebCore/platform/Timer.cpp:336
#40 0x0126b7a8 in WebCore::TimerBase::sharedTimerFired () at /Volumes/Data/WebKit/WebCore/platform/Timer.cpp:353
#41 0x0126ab98 in timerFired () at /Volumes/Data/WebKit/WebCore/platform/mac/SharedTimerMac.cpp:46
#42 0x907f2578 in __CFRunLoopDoTimer ()
#43 0x907deef8 in __CFRunLoopRun ()
#44 0x907de4ac in CFRunLoopRunSpecific ()
#45 0x93298b20 in RunCurrentEventLoopInMode ()
#46 0x932981b4 in ReceiveNextEventCommon ()
#47 0x93298020 in BlockUntilNextEventMatchingListInMode ()
#48 0x9379eae4 in _DPSNextEvent ()
#49 0x9379e7a8 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#50 0x00006740 in ?? ()
#51 0x9379acec in -[NSApplication run] ()
#52 0x9388b87c in NSApplicationMain ()
#53 0x0005c77c in ?? ()
#54 0x0005c624 in ?? ()

And a backtrace after rmvScroll(msg) has run showing where the final relayout occurs:

Breakpoint 4, WebCore::CSSStyleSelector::matchRulesForList (this=0x187f1e40, rules=0x1700a910, firstRuleIndex=@0xbfffddbc, lastRuleIndex=@0xbfffddc0) at /Volumes/Data/WebKit/WebCore/css/cssstyleselector.cpp:435
435     fprintf(stderr, ">>> CSSStyleRule = '%s' ", rule->selectorText().ascii().data());
#0  WebCore::CSSStyleSelector::matchRulesForList (this=0x187f1e40, rules=0x1700a910, firstRuleIndex=@0xbfffddbc, lastRuleIndex=@0xbfffddc0) at /Volumes/Data/WebKit/WebCore/css/cssstyleselector.cpp:435
#1  0x0114fc9c in WebCore::CSSStyleSelector::matchRules (this=0x187f1e40, rules=0x18f28610, firstRuleIndex=@0xbfffddbc, lastRuleIndex=@0xbfffddc0) at /Volumes/Data/WebKit/WebCore/css/cssstyleselector.cpp:395
#2  0x0115ef54 in WebCore::CSSStyleSelector::styleForElement (this=0x187f1e40, e=0x189854e0, defaultParent=0x0, allowSharing=true, resolveForRootDefault=false) at /Volumes/Data/WebKit/WebCore/css/cssstyleselector.cpp:877
#3  0x012b9844 in WebCore::Element::recalcStyle (this=0x189854e0, change=WebCore::Node::NoChange) at /Volumes/Data/WebKit/WebCore/dom/Element.cpp:676
#4  0x012b9bc4 in WebCore::Element::recalcStyle (this=0x1878e5d0, change=WebCore::Node::NoChange) at /Volumes/Data/WebKit/WebCore/dom/Element.cpp:716
#5  0x012b9bc4 in WebCore::Element::recalcStyle (this=0x1893c670, change=WebCore::Node::NoChange) at /Volumes/Data/WebKit/WebCore/dom/Element.cpp:716
#6  0x012b9bc4 in WebCore::Element::recalcStyle (this=0x1893c730, change=WebCore::Node::NoChange) at /Volumes/Data/WebKit/WebCore/dom/Element.cpp:716
#7  0x012b9bc4 in WebCore::Element::recalcStyle (this=0x195bd150, change=WebCore::Node::NoChange) at /Volumes/Data/WebKit/WebCore/dom/Element.cpp:716
#8  0x012b9bc4 in WebCore::Element::recalcStyle (this=0x1976b6a0, change=WebCore::Node::NoChange) at /Volumes/Data/WebKit/WebCore/dom/Element.cpp:716
#9  0x012b9bc4 in WebCore::Element::recalcStyle (this=0x1873c400, change=WebCore::Node::NoChange) at /Volumes/Data/WebKit/WebCore/dom/Element.cpp:716
#10 0x01100184 in WebCore::Document::recalcStyle (this=0x2bcb600, change=WebCore::Node::NoChange) at /Volumes/Data/WebKit/WebCore/dom/Document.cpp:1006
#11 0x010f6960 in WebCore::Document::updateRendering (this=0x2bcb600) at /Volumes/Data/WebKit/WebCore/dom/Document.cpp:1028
#12 0x012ec624 in KJS::ScheduledAction::execute (this=0x189f1f20, window=0x16f9fdc0) at /Volumes/Data/WebKit/WebCore/bindings/js/kjs_window.cpp:1940
#13 0x012ef734 in KJS::Window::timerFired (this=0x16f9fdc0, timer=0x1894ae10) at /Volumes/Data/WebKit/WebCore/bindings/js/kjs_window.cpp:2054
#14 0x012ef7d0 in KJS::DOMWindowTimer::fired (this=0x1894ae10) at /Volumes/Data/WebKit/WebCore/bindings/js/kjs_window.cpp:2641
#15 0x0126b6dc in WebCore::TimerBase::fireTimers (fireTime=1179386457.14042, firingTimers=@0xbfffe480) at /Volumes/Data/WebKit/WebCore/platform/Timer.cpp:336
#16 0x0126b7a8 in WebCore::TimerBase::sharedTimerFired () at /Volumes/Data/WebKit/WebCore/platform/Timer.cpp:353
#17 0x0126ab98 in timerFired () at /Volumes/Data/WebKit/WebCore/platform/mac/SharedTimerMac.cpp:46
#18 0x907f2578 in __CFRunLoopDoTimer ()
#19 0x907deef8 in __CFRunLoopRun ()
#20 0x907de4ac in CFRunLoopRunSpecific ()
#21 0x93298b20 in RunCurrentEventLoopInMode ()
#22 0x932981b4 in ReceiveNextEventCommon ()
#23 0x93298020 in BlockUntilNextEventMatchingListInMode ()
#24 0x9379eae4 in _DPSNextEvent ()
#25 0x9379e7a8 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#26 0x00006740 in ?? ()
#27 0x9379acec in -[NSApplication run] ()
#28 0x9388b87c in NSApplicationMain ()
#29 0x0005c77c in ?? ()
#30 0x0005c624 in ?? ()
------- Comment #22 From 2007-05-17 00:52:56 PST -------
Based on the information in the last few comments, it should be possible to create a test case for this issue, although if someone else wants to take a stab at it before tomorrow, be my guest!
------- Comment #23 From 2007-05-17 01:03:17 PST -------
updateStyleSelector happens synchronously when insertRule/deleteRule are called.  So it should be up to date.  Not sure what is happening here.
------- Comment #24 From 2007-05-17 01:44:05 PST -------
(In reply to comment #23)
> updateStyleSelector happens synchronously when insertRule/deleteRule are
> called.  So it should be up to date.  Not sure what is happening here.

Okay, I'll try to figure out what's not getting updated properly.
------- Comment #25 From 2007-05-20 02:07:40 PST -------
Created an attachment (id=14634) [details]
Reduction (will crash when you click Test)

The reduction includes comments on how it works.
------- Comment #26 From 2007-05-20 10:04:43 PST -------
Wondering if there's an elegant fix that doesn't involve adding another bit of state to Document.
------- Comment #27 From 2007-05-20 11:59:49 PST -------
(From update of attachment 14634 [details])
Not that it makes any difference, but I used the wrong attribute in the test: where it says "src" it should say "href".

I discovered that when I tried to replace the URL with something that takes a long time to load. If you do that and comment-out the last line of the script, then the color will not change from pink to black until the slow-loading URL has finished loading. That's a less catastrophic symptom of the same bug, namely that updateStyleSelector() bails out when it should not.
------- Comment #28 From 2007-05-20 15:58:21 PST -------
Created an attachment (id=14637) [details]
Keep updating the style selector once you calculated it

The layout tests fail to crash a release build of TOT, maybe because of fast malloc not trashing the deleted style rule immediately. One of them crashes a debug build quite reliably. The other one not so much (but crashes eventually in Safari).
------- Comment #29 From 2007-05-21 01:19:52 PST -------
(From update of attachment 14637 [details])
r=me

This bug is just plain cool.
------- Comment #30 From 2007-05-23 19:10:32 PST -------
Committed revision 21690.