Bug 121513

Summary: Javascript code causes crash, signal 6 (SIGABRT)
Product: [Applications] konqueror Reporter: Gavin Rogers <g4sys>
Component: khtmlAssignee: Konqueror Developers <konq-bugs>
Status: RESOLVED FIXED    
Severity: crash CC: maksim
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: openSUSE   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Gavin Rogers 2006-02-06 23:24:58 UTC
Version:           3.5.0 (using KDE KDE 3.5.0KDE 3.4.3)
Installed from:    SuSE RPMsUbuntu Packages
Compiler:          gcc-4.0 Configured with: ../src/configure -v --enable-languages=c,c++,java,f95,objc,ada,treelang --prefix=/usr --with-gxx-include-dir=/usr/include/c++/4.0.2 --enable-shared --with-system-zlib --libexecdir=/usr/lib --enable-nls --without-included-gettext --enable-threads=posix --program-suffix=-4.0 --enable-__cxa_atexit --enable-libstdcxx-allocator=mt --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-gc=boehm --enable-java-awt=gtk-default --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-4.0-1.4.2.0/jre --enable-mpfr --disable-softfloat --enable-targets=powerpc-linux,powerpc64-linux --with-cpu=default32 --disable-werror --enable-checking=release powerpc-linux-gnu
Thread model: posix
gcc version 4.0.2 20050808 (prerelease) (Ubuntu 4.0.1-4ubuntu9)
OS:                Linux

How to reproduce on i386 or PPC linux, any version of KDE/Konqueror:
http://www.javascriptkit.com/script/script2/tengcalendar.shtml
go to above URL and click on the calender. Then try to change the month from January to any other month. VOILA it will crash.

It seemss to me that the code in question is as follows:

<td colspan='7'><table border=0 width='100%' cellpadding=0 cellspacing=0><tr><td align='left'>
<select name="MonthSelector" onChange="javascript:winMain.Cal.SwitchMth(this.selectedIndex);winMain.RenderCal();">
<option  value >January
<option  value >February
<option Selected value >March
<option  value >April
<option  value >May
<option  value >June
<option  value >July
<option  value >August

<option  value >September
<option  value >October
<option  value >November
<option  value >December
</select></td>


Backtrace:

(no debugging symbols found)
Using host libthread_db library "/lib/libthread_db.so.1".
(no debugging symbols found)
(no debugging symbols found)
[Thread debugging using libthread_db enabled]
[New Thread 805577632 (LWP 16056)]
0x0e305c50 in __waitpid_nocancel () from /lib/libpthread.so.0
#0  0x0e305c50 in __waitpid_nocancel () from /lib/libpthread.so.0
#1  0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#2  0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#3  0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#4  0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#5  0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#6  0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#7  0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#8  0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#9  0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#10 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#11 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#12 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#13 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#14 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#15 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#16 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#17 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#18 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#19 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#20 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#21 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#22 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#23 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#24 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#25 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#26 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#27 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#28 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#29 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#30 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#31 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#32 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#33 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#34 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#35 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#36 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#37 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#38 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#39 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#40 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#41 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#42 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#43 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#44 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#45 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#46 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#47 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#48 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#49 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#50 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#51 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#52 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#53 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#54 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#55 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#56 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#57 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
#58 0x0f510a44 in KCrash::defaultCrashHandler (sig=6) at kcrash.cpp:251
Comment 1 Maksim Orlovich 2006-02-06 23:29:08 UTC
Takes a bit of clicking around, but I can confirm

Using host libthread_db library "/lib/tls/libthread_db.so.1".
`shared object read from target memory' has disappeared; keeping its symbols.
[Thread debugging using libthread_db enabled]
[New Thread -1231329600 (LWP 18451)]
[KCrash handler]
#6  0xffffe410 in __kernel_vsyscall ()
#7  0xb6a60f21 in raise () from /lib/tls/libc.so.6
#8  0xb6a6286b in abort () from /lib/tls/libc.so.6
#9  0xb6a5a065 in __assert_fail () from /lib/tls/libc.so.6
#10 0xb624e8c1 in khtml::RenderArena::free (this=0x8811870, size=0, 
    ptr=0x4813) at /code/KDE/kde3/kdelibs/khtml/rendering/render_arena.cpp:113
#11 0xb623b1bb in khtml::RenderObject::arenaDelete (this=0x87e7218, 
    arena=0x8811870, base=0x87e71f0)
    at /code/KDE/kde3/kdelibs/khtml/rendering/render_object.cpp:1543
#12 0xb623b1fe in khtml::RenderObject::arenaDelete (this=0x87e7218, 
    arena=0x8811870)
    at /code/KDE/kde3/kdelibs/khtml/rendering/render_object.cpp:1550
#13 0xb62667fe in khtml::RenderWidget::deref (this=0x87e71f0)
    at /code/KDE/kde3/kdelibs/khtml/rendering/render_replaced.cpp:813
#14 0xb6271376 in khtml::RenderSelect::slotSelected (this=0x87e71f0, index=)
    at /code/KDE/kde3/kdelibs/khtml/rendering/render_form.cpp:1127
#15 0xb62720e0 in khtml::RenderSelect::qt_invoke (this=0x87e71f0, _id=3, 
    _o=0xbf976fdc) at ../khtml/rendering/render_form.moc:625
#16 0xb728485b in QObject::activate_signal (this=0x8831370, clist=0x87c6c50, 
    o=0xbf976fdc) at kernel/qobject.cpp:2392
#17 0xb7284d42 in QObject::activate_signal (this=0x8831370, signal=2, param=4)
    at kernel/qobject.cpp:2485
#18 0xb74f8bb6 in QComboBox::activated () at ../include/qrect.h:248
#19 0xb72f1384 in QComboBox::internalActivate () at tools/qstring.h:218
#20 0xb74f8d61 in QComboBox::qt_invoke () at ../include/qrect.h:248
#21 0xb7b2fd41 in KComboBox::qt_invoke (this=0x8831370, _id=142807920, 
    _o=0xbf97715c) at ./kdeui/kcombobox.moc:252
#22 0xb728485b in QObject::activate_signal (this=0x876e740, clist=0x87e9390, 
    o=0xbf97715c) at kernel/qobject.cpp:2392
#23 0xb7284d42 in QObject::activate_signal (this=0x876e740, signal=8, param=4)
    at kernel/qobject.cpp:2485
#24 0xb74fddb0 in QListBox::selected () at ../include/qrect.h:248
#25 0xb7321960 in QListBox::mouseDoubleClickEvent () at tools/qstring.h:218
#26 0xb72aec44 in QWidget::event (this=0x876e740, e=0xbf97741c)
    at kernel/qwidget.cpp:4682
#27 0xb7244508 in QApplication::internalNotify (this=0x0, receiver=0x876e740, 
    e=0xbf97741c) at kernel/qapplication.cpp:2635
#28 0xb72447fb in QApplication::notify (this=0xbf977d8c, receiver=0x876e740, 
    e=0xbf97741c) at kernel/qapplication.cpp:2421
#29 0xb77a8dd2 in KApplication::notify (this=0xbf977d8c, receiver=0x876e740, 
    event=0xbf97741c) at /code/KDE/kde3/kdelibs/kdecore/kapplication.cpp:550
#30 0xb72f1df7 in QComboBox::eventFilter () at tools/qstring.h:218
#31 0xb7b2deb3 in KComboBox::eventFilter (this=0x8831370, o=0x876e740, 
    ev=0xbf977680) at /code/KDE/kde3/kdelibs/kdeui/kcombobox.cpp:180
#32 0xb626d71f in khtml::ComboBoxWidget::eventFilter (this=0x8831370, 
    dest=0x876e740, e=0xbf977680)
    at /code/KDE/kde3/kdelibs/khtml/rendering/render_form.cpp:865
#33 0xb728554a in QObject::activate_filters (this=0x876e740, e=0xbf977680)
    at kernel/qobject.cpp:904
#34 0xb72855a7 in QObject::event (this=0x876e740, e=0xbf977680)
    at kernel/qobject.cpp:737
#35 0xb72aebc8 in QWidget::event (this=0x876e740, e=0xbf977680)
    at kernel/qwidget.cpp:4658
#36 0xb7244508 in QApplication::internalNotify (this=0x0, receiver=0x876e740, 
    e=0xbf977680) at kernel/qapplication.cpp:2635
#37 0xb72447fb in QApplication::notify (this=0xbf977d8c, receiver=0x87fa1a0, 
    e=0xbf977938) at kernel/qapplication.cpp:2421
#38 0xb77a8dd2 in KApplication::notify (this=0xbf977d8c, receiver=0x87fa1a0, 
    event=0xbf977938) at /code/KDE/kde3/kdelibs/kdecore/kapplication.cpp:550
#39 0xb71fb992 in QApplication::sendSpontaneousEvent (receiver=0x87fa1a0, 
    event=0xbf977938) at kernel/qapplication.h:494
#40 0xb71f9c9a in QETWidget::translateMouseEvent (this=0x87fa1a0, 
    event=0xbf977bdc) at kernel/qapplication_x11.cpp:4228
#41 0xb71fa6e7 in QApplication::x11ProcessEvent (this=0xbf977d8c, 
    event=0xbf977bdc) at kernel/qapplication_x11.cpp:3448
#42 0xb7208393 in QEventLoop::processEvents (this=0x80fd420, flags=4)
    at kernel/qeventloop_x11.cpp:192
#43 0xb72515dc in QEventLoop::enterLoop () at ../include/qshared.h:48
#44 0xb7251541 in QEventLoop::exec () at ../include/qshared.h:48
#45 0xb7240330 in QApplication::exec (this=0xbf977d8c)
    at kernel/qapplication.cpp:2758
#46 0xb67187bc in kdemain () from /opt/kde3.4/lib/libkdeinit_konqueror.so
#47 0xb7675750 in kdeinitmain () from /opt/kde3.4/lib/kde3/konqueror.so
#48 0x0804f037 in launch (argc=2, _name=0x80c5dcc "konqueror", 
    args=0x80c5de0 "\001", cwd=0x0, envc=1, envs=0x80c5df1 "", 
    reset_env=false, tty=0x0, avoid_loops=false, startup_id_str=0x805192b "0")
    at /code/KDE/kde3/kdelibs/kinit/kinit.cpp:637
#49 0x0804f73a in handle_launcher_request (sock=8)
    at /code/KDE/kde3/kdelibs/kinit/kinit.cpp:1203
#50 0x0804fc79 in handle_requests (waitForPid=0)
    at /code/KDE/kde3/kdelibs/kinit/kinit.cpp:1404
#51 0x080503c3 in main (argc=2, argv=0xbf978714, envp=0xbf978720)
    at /code/KDE/kde3/kdelibs/kinit/kinit.cpp:1848
Comment 2 Gavin Rogers 2006-02-06 23:44:12 UTC
I should have done this earlier but... if you enable the JS debugger, konqueror detects the problem:
Error: node : ReferenceError - Can't find variable: NewCal

So this is a coding error (not mine! it is TengYong Ng's fault!) but still konqueror should not crash.

Also, SadEagle asked me to add the console output. Here it is:
gavin@iBook:~$ konqueror
pure virtual method called
terminate called without an active exception
KCrash: Application 'konqueror' crashing...
    

Comment 3 Maksim Orlovich 2006-02-11 07:21:03 UTC
SVN commit 508195 by orlovich:

Fix a very subtle bug (the analysis to which was under my nose all the time):
when a document gets detached from inside an event handler of a widget, it 
detaches the tree, destroys the renderer arena and sets a new one. 
The problem is, the RenderWidget doesn't actually get detached, as it's held
by a protecting refcount. The end result is that when the deref() is 
called on the RenderWidget, it tries to free itself... from the new arena.
Hence, memory corruption, crashes, etc. Except, of course, it's within the 
arena, so valgrind doesn't see anything. And if you build without the arena?
A very truthful assert saying that the arena pointer got changed, somehow --- 
which yours truly interpreted as memory corruption, and was bewildered by the 
lack of vg warnings on it. 

My fix is to have the RenderWidget a co-owner of the arena, with its own pointer,
and ability to prolong its life. 

Oh, and if any of the build system gods is still reading, I would be eternally grateful 
if someone added a configure check for Valgrind headers, so I can instrument this
damn arena thing with VG hints once and for all, and save all of us bajillions of times
debugging render tree messes.

BUG:121513




 M  +2 -1      rendering/render_arena.h  
 M  +7 -3      rendering/render_replaced.cpp  
 M  +5 -0      rendering/render_replaced.h  
 M  +5 -11     xml/dom_docimpl.cpp  
 M  +2 -2      xml/dom_docimpl.h  


--- branches/KDE/3.5/kdelibs/khtml/rendering/render_arena.h #508194:508195
@@ -37,6 +37,7 @@
 #define RENDERARENA_H
 
 #include "misc/arena.h"
+#include "misc/shared.h"
 
 #include <stdlib.h>
 
@@ -45,7 +46,7 @@
 #define KHTML_MAX_RECYCLED_SIZE 400
 #define KHTML_ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y))
 
-class RenderArena {
+class RenderArena: public Shared<RenderArena> {
 public:
    RenderArena(unsigned int arenaSize = 4096);
     ~RenderArena();
--- branches/KDE/3.5/kdelibs/khtml/rendering/render_replaced.cpp #508194:508195
@@ -97,7 +97,8 @@
     m_widget = 0;
     // a widget doesn't support being anonymous
     assert(!isAnonymous());
-    m_view = node->getDocument()->view();
+    m_view  = node->getDocument()->view();
+    m_arena.reset(renderArena());
     m_resizePending = false;
     m_discardResizes = false;
 
@@ -810,8 +811,11 @@
 {
     if (_ref) _ref--;
 //     qDebug( "deref(%p): width get count is %d", this, _ref);
-    if (!_ref)
-        arenaDelete(renderArena());
+    if (!_ref) {
+        khtml::SharedPtr guard(m_arena); //Since delete on us gets called -first-,
+                                         //before the arena free
+        arenaDelete(m_arena.get());
+    }
 }
 
 FindSelectionResult RenderReplaced::checkSelectionPoint(int _x, int _y, int _tx, int _ty, DOM::NodeImpl*& node, int &offset, SelPointState &)
--- branches/KDE/3.5/kdelibs/khtml/rendering/render_replaced.h #508194:508195
@@ -131,6 +131,11 @@
     QWidget *m_widget;
     KHTMLView* m_view;
 
+    //Because we mess with normal detach due to ref/deref,
+    //we need to keep track of the arena ourselves
+    //so it doesn't get yanked from us, etc.
+    SharedPtr<RenderArena> m_arena; 
+
     bool m_resizePending;
     bool m_discardResizes;
 
--- branches/KDE/3.5/kdelibs/khtml/xml/dom_docimpl.cpp #508194:508195
@@ -296,7 +296,7 @@
     m_textColor = Qt::black;
 
     m_view = v;
-    m_renderArena = 0;
+    m_renderArena.reset();
 
     KHTMLFactory::ref();
 
@@ -393,10 +393,7 @@
     if ( m_hoverNode )
         m_hoverNode->deref();
 
-    if (m_renderArena){
-	delete m_renderArena;
-	m_renderArena = 0;
-    }
+    m_renderArena.reset();
 
     KHTMLFactory::deref();
 }
@@ -1160,13 +1157,13 @@
         setPaintDevice( m_view );
 
     if (!m_renderArena)
-	m_renderArena = new RenderArena();
+	m_renderArena.reset(new RenderArena());
 
     // Create the rendering tree
     assert(!m_styleSelector);
     m_styleSelector = new CSSStyleSelector( this, m_usersheet, m_styleSheets, m_url,
                                             !inCompatMode() );
-    m_render = new (m_renderArena) RenderCanvas(this, m_view);
+    m_render = new (m_renderArena.get()) RenderCanvas(this, m_view);
     m_styleSelector->computeFontSizes(paintDeviceMetrics(), m_view ? m_view->part()->zoomFactor() : 100);
     recalcStyle( Force );
 
@@ -1197,10 +1194,7 @@
 
     m_view = 0;
 
-    if ( m_renderArena ) {
-	delete m_renderArena;
-	m_renderArena = 0;
-    }
+    m_renderArena.reset();
 }
 
 void DocumentImpl::setVisuallyOrdered()
--- branches/KDE/3.5/kdelibs/khtml/xml/dom_docimpl.h #508194:508195
@@ -295,7 +295,7 @@
     virtual void attach();
     virtual void detach();
 
-    khtml::RenderArena* renderArena() { return m_renderArena; }
+    khtml::RenderArena* renderArena() { return m_renderArena.get(); }
 
     // to get visually ordered hebrew and arabic pages right
     void setVisuallyOrdered();
@@ -654,7 +654,7 @@
     //Cache for getElementById
     mutable ElementMappingCache m_getElementByIdCache;
 
-    khtml::RenderArena* m_renderArena;
+    khtml::SharedPtr<khtml::RenderArena> m_renderArena;
 private:
     mutable DOMString m_domain;
 };