[Kde-bindings] QtRuby crashes

Richard Dale rdale at foton.es
Wed Nov 7 11:04:11 UTC 2007


On Tuesday 06 November 2007 16:46:31 Sebastian Sauer wrote:
> If we are using QtRuby embedded in an application using Kross, we keep to
> get crashes on application exit. The backtrace looks like;
>
> [KCrash handler]
> #5  0x00002aaac1b56a86 in QHashNode (this=0x13fed20, key0=@0x70,
> value0=@0x78) at /home/kde4/qt4-copy/include/QtCore/qhash.h:186
> #6  0x00002aaac1b56bb5 in QHash<void*, unsigned long*>::duplicateNode (
>     node=0x60, newNode=0x13fed20)
>     at /home/kde4/qt4-copy/include/QtCore/qhash.h:473
> #7  0x00002aea9e100672 in QHashData::detach_helper (this=0x2645510,
>     node_duplicate=0x2aaac1b56b66 <QHash<void*, unsigned
> long*>::duplicateNode(QHashData::Node*, void*)>, nodeSize=32) at
> tools/qhash.cpp:184
> #8  0x00002aaac1b586ac in QHash<void*, unsigned long*>::detach_helper (
>     this=0x2aaac1d9d580) at /home/kde4/qt4-copy/include/QtCore/qhash.h:535
> #9  0x00002aaac1b58716 in QHash<void*, unsigned long*>::detach (
>     this=0x2aaac1d9d580) at /home/kde4/qt4-copy/include/QtCore/qhash.h:253
> #10 0x00002aaac1b587d3 in QHash<void*, unsigned long*>::remove (
>     this=0x2aaac1d9d580, akey=@0x7fff0ce38100)
>     at /home/kde4/qt4-copy/include/QtCore/qhash.h:730
> #11 0x00002aaac1b555cf in unmapPointer (o=0x2533aa0, classId=260,
>     lastptr=0x235b8d0)
>     at /home/kde4/svn/_src/KDE/kdebindings/ruby/qtruby/src/Qt.cpp:262
> #12 0x00002aaac1b62c02 in smokeruby_free (p=0x2533aa0)
>     at /home/kde4/svn/_src/KDE/kdebindings/ruby/qtruby/src/handlers.cpp:347
> #13 0x00002aaac165bd8e in rb_gc_call_finalizer_at_exit ()
>    from /usr/lib/libruby1.8.so.1.8
>
> I did investigate this a bit during hours of testing, I did note that the
> QHash<void *, VALUE *> pointer_map; defined within Qt.cpp does got invalid
> while cleanup. It seems for whatever reason the internal Node* instances
> got partly lost somewhere at the shutdown and therefore it keeps to crash.
> Even a simple foreach(Value*, pointer_map); could trigger this. During
> testing I even got a more useful backtrace that shows, that something goes
> totaly wrong;
>
> [KCrash handler]
> #5  0x00002b8da35e1765 in raise () from /lib64/libc.so.6
> #6  0x00002b8da35e31c0 in abort () from /lib64/libc.so.6
> #7  0x00002b8d98c43e48 in qt_message_output (msgType=QtFatalMsg,
>     buf=0x7fff122cf400 "ASSERT: \"*node == e || (*node)->next\" in
> file /home/kde4/qt4-copy/include/QtCore/qhash.h, line 826") at
> global/qglobal.cpp:2145
> #8  0x00002b8d98c43f69 in qFatal (
>     msg=0x2b8d98d324f8 "ASSERT: \"%s\" in file %s, line %d")
>     at global/qglobal.cpp:2376
> #9  0x00002b8d98c440bd in qt_assert (
>     assertion=0x2aaac5bba193 "*node == e || (*node)->next",
>     file=0x2aaac5bba168 "/home/kde4/qt4-copy/include/QtCore/qhash.h",
> line=826)
>     at global/qglobal.cpp:1904
>
> The following "patch" fixes this 100% and no crashes do popup any longer
> (yes, I know that the solution may suck cause a lookup now may take longer,
> but at least it does not crash any more :)
>
> Index: src/Qt.cpp
> ===================================================================
> --- src/Qt.cpp  (revision 731455)
> +++ src/Qt.cpp  (working copy)
> @@ -94,7 +94,7 @@
>  int do_debug = qtdb_none;
>  #endif
>
> -QHash<void *, VALUE *> pointer_map;
> +QMap<void *, VALUE *> pointer_map;
>  int object_count = 0;
>
>  QHash<QByteArray, Smoke::Index *> methcache;
Hmm, an interesting problem. I looked up the difference between QHash and QMap 
and it says:

"QMap and QHash provide very similar functionality. The differences are:
QHash provides faster lookups than QMap. (See Algorithmic Complexity for 
details.)
When iterating over a QHash, the items are arbitrarily ordered. With QMap, the 
items are always sorted by key.
The key type of a QHash must provide operator==() and a global qHash(Key) 
function. The key type of a QMap must provide operator<() specifying a total 
order."

So in theory the above patch shouldn't make any difference as they should 
behave the same with respect to clean up on exit. 

I've had a problem with the plasma ruby bindings in that after a while virtual 
method or slot callbacks fail with what looks like a memory corruption 
problem. That isn't when the hash is freed on application exit, but I wonder 
if the two problems are related in some way. I'll try the plasma clock using 
a QMap and see if it makes any difference.

I would rather we understood what was going on better before applying the 
patch though. The pointer_map entries don't need to be in a sorted order, and 
so QHash should be the correct type to use.

-- Richard



More information about the Kde-bindings mailing list