Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / qt / 2009-01

Qt deffered deletion (QObject_deleteLater())

6 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

zeljko

Hi all,

! PLEASE READ THIS UNTIL THE END (not debugging info but my text after that) !

I've found strange crashes inside qt libs, and of course found why it happens. It rarely happens on small apps, but with big apps and heavy pressure (many forms opened & closed), our lcl app segfaults like this :

[Switching to Thread 1073923872 (LWP 26845)]
0x0636dc11 in QHash<QObject*, QHashDummyValue>::remove () from /usr/lib/libQtCore.so.4
(gdb) bt
#0 0x0636dc11 in QHash<QObject*, QHashDummyValue>::remove () from /usr/lib/libQtCore.so.4
#1 0x06369f61 in qt_removeObject () from /usr/lib/libQtCore.so.4 #2 0x0636ba9d in QObject::~QObject () from /usr/lib/libQtCore.so.4 #3 0x05b7d2a4 in QAction::~QAction () from /usr/lib/libQtGui.so.4 #4 0x06366753 in QObjectPrivate::deleteChildren () from /usr/lib/libQtCore.so.4
#5 0x05bd4a4e in QWidget::~QWidget () from /usr/lib/libQtGui.so.4 #6 0x05f490ec in QMenu::~QMenu () from /usr/lib/libQtGui.so.4 #7 0x063653a6 in qDeleteInEventHandler () from /usr/lib/libQtCore.so.4 #8 0x063679d6 in QObject::event () from /usr/lib/libQtCore.so.4 #9 0x05bcd2c8 in QWidget::event () from /usr/lib/libQtGui.so.4 #10 0x05f4440a in QMenu::event () from /usr/lib/libQtGui.so.4 #11 0x05b80f41 in QApplicationPrivate::notify_helper () from /usr/lib/libQtGui.so.4
#12 0x05b810ae in QApplication::notify () from /usr/lib/libQtGui.so.4 #13 0x063578f0 in QCoreApplication::notifyInternal () from /usr/lib/libQtCore.so.4
#14 0x0635ad4b in QCoreApplicationPrivate::sendPostedEvents () from /usr/lib/libQtCore.so.4
#15 0x0635ade5 in QCoreApplication::sendPostedEvents () from /usr/lib/libQtCore.so.4
#16 0x0635b036 in QCoreApplication::processEvents () from /usr/lib/libQtCore.so.4
#17 0x4b7393ee in QCoreApplication_processEvents () from /usr/lib/libqt4intf.so

OR LIKE THIS

[Thread debugging using libthread_db enabled]
[New Thread 1073923872 (LWP 3553)]
*** glibc detected *** corrupted double-linked list: 0x09bc4f00 ***

Program received signal SIGABRT, Aborted.
[Switching to Thread 1073923872 (LWP 3553)]
0x40000424 in __kernel_vsyscall ()
(gdb) bt
#0 0x40000424 in __kernel_vsyscall ()
#1 0x00a32955 in raise () from /lib/tls/libc.so.6 #2 0x00a34319 in abort () from /lib/tls/libc.so.6 #3 0x00a65f9a in __libc_message () from /lib/tls/libc.so.6 #4 0x00a6bf00 in malloc_consolidate () from /lib/tls/libc.so.6 #5 0x00a6ce03 in _int_malloc () from /lib/tls/libc.so.6 #6 0x00a6e135 in _int_realloc () from /lib/tls/libc.so.6 #7 0x00a6f2a6 in realloc () from /lib/tls/libc.so.6 #8 0x0627a874 in qRealloc () from /usr/lib/libQtCore.so.4 #9 0x062a27e1 in QListData::realloc () from /usr/lib/libQtCore.so.4 #10 0x062a28d9 in QListData::append () from /usr/lib/libQtCore.so.4 #11 0x05b8a4b3 in QList<QWidget*>::append () from /usr/lib/libQtGui.so.4 #12 0x05b8ad39 in QSet<QWidget*>::toList () from /usr/lib/libQtGui.so.4 #13 0x05b84546 in QApplication::allWidgets () from /usr/lib/libQtGui.so.4 #14 0x05b8459d in QApplication::topLevelWidgets () from /usr/lib/libQtGui.so.4 #15 0x05b88269 in QApplicationPrivate::leaveModal () from /usr/lib/libQtGui.so.4
#16 0x05c017c6 in QWidget::destroy () from /usr/lib/libQtGui.so.4 #17 0x05bd434e in QWidget::~QWidget () from /usr/lib/libQtGui.so.4 #18 0x063653a6 in qDeleteInEventHandler () from /usr/lib/libQtCore.so.4 #19 0x063679d6 in QObject::event () from /usr/lib/libQtCore.so.4 #20 0x05bcd2c8 in QWidget::event () from /usr/lib/libQtGui.so.4 #21 0x05b80f41 in QApplicationPrivate::notify_helper () from /usr/lib/libQtGui.so.4
#22 0x05b810ae in QApplication::notify () from /usr/lib/libQtGui.so.4 #23 0x063578f0 in QCoreApplication::notifyInternal () from /usr/lib/libQtCore.so.4
#24 0x0635ad4b in QCoreApplicationPrivate::sendPostedEvents () from /usr/lib/libQtCore.so.4
#25 0x0635ade5 in QCoreApplication::sendPostedEvents () from /usr/lib/libQtCore.so.4
#26 0x0635b036 in QCoreApplication::processEvents () from /usr/lib/libQtCore.so.4
#27 0x4b7393ee in QCoreApplication_processEvents () from /usr/lib/libqt4intf.so

OR LIKE THIS

Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 1073923872 (LWP 18964)]
0x0636b7db in QObject::~QObject () from /usr/lib/libQtCore.so.4 (gdb) bt
#0 0x0636b7db in QObject::~QObject () from /usr/lib/libQtCore.so.4 #1 0x05b7d2a4 in QAction::~QAction () from /usr/lib/libQtGui.so.4 #2 0x06366753 in QObjectPrivate::deleteChildren () from /usr/lib/libQtCore.so.4
#3 0x05bd4a4e in QWidget::~QWidget () from /usr/lib/libQtGui.so.4 #4 0x05f490ec in QMenu::~QMenu () from /usr/lib/libQtGui.so.4 #5 0x063653a6 in qDeleteInEventHandler () from /usr/lib/libQtCore.so.4 #6 0x063679d6 in QObject::event () from /usr/lib/libQtCore.so.4 #7 0x05bcd2c8 in QWidget::event () from /usr/lib/libQtGui.so.4 #8 0x05f4440a in QMenu::event () from /usr/lib/libQtGui.so.4 #9 0x05b80f41 in QApplicationPrivate::notify_helper () from /usr/lib/libQtGui.so.4
#10 0x05b810ae in QApplication::notify () from /usr/lib/libQtGui.so.4 #11 0x063578f0 in QCoreApplication::notifyInternal () from /usr/lib/libQtCore.so.4
#12 0x0635ad4b in QCoreApplicationPrivate::sendPostedEvents () from /usr/lib/libQtCore.so.4
#13 0x0635ade5 in QCoreApplication::sendPostedEvents () from /usr/lib/libQtCore.so.4
#14 0x0635b036 in QCoreApplication::processEvents () from /usr/lib/libQtCore.so.4
#15 0x4b7393ee in QCoreApplication_processEvents () from /usr/lib/libqt4intf.so

END DEBUGGING INFO

So I decided to find out what's up.
1.Problem exists on Linux, Win32 and Mac.
2.Tested with our ERP app , ported from K3/D7
3.There's no mem leaks in our app (according to heaptrc). 4.Problem raises after few hours of work, when many forms opened & closed. (see debug logs above).
5.I'm talking about qt-4.4 and qt-4.5 !

So after googling (about similar error gdb traces in qt4) and some small tests I decide to remove QEvent::DefferedDelete from our QApplication_processMessages(), and of course changed some code inside qtwidgets & qtobjects (there's no more QObject_deleteLater() per default inside our qtlcl !)
BINGO ! Seem that our app is working faster (seem like Laz IDE work faster too - no more wait for deffered deletion) AND NO MORE STRANGE SEGFAULTS ! :). QEvent::DefferedDelete produced mess & unnecessary breaks inside processMessages() (trolltech guys said that DefferedDelete should not be used anymore as of Qt-4.4 (currently, we are using workaround inside TQtWidgetSet.AppProcessMessages() )!.

Patch is ready - less or more (still some problem pending with destroying of popup menus)...working on that one at the moment.

So my question would be (since I don't want to break qt-4.3 users), should I ifdef it like USE_QT_44 OR QT_NO_DEFFERED_DELETION ?

Question for Den: Why we don't have QObject_destroyed_event() inside bindings, there's public signal QObject::destroyed(QObject* obj = 0) according to qt docs ?

thanks,

zeljko

Reply by email

Den Jean
to zeljko
zeljko wrote
Question for Den: Why we don't have QObject_destroyed_event() inside bindings, there's public signal QObject::destroyed(QObject* obj = 0) according to qt docs ?

will fix this

Reply by email

Paul Ishenin
to zeljko: ! PLEASE READ THIS UNTIL THE END (not debugging info but my text after that) ! I've found…
zeljko wrote
So my question would be (since I don't want to break qt-4.3 users), should I ifdef it like USE_QT_44 OR QT_NO_DEFFERED_DELETION ?

If you dont remember we had some problems with object destroying inside their events. Because of that we are using postponed object destroying. If your new code will work with this feel free to commit it.

Best regards,
Paul Ishenin.

Reply by email

zeljko
to Paul Ishenin
Paul Ishenin wrote 7 lines
zeljko wrote: > So my question would be (since I don't want to break qt-4.3 users), > should I ifdef it like USE_QT_44 OR QT_NO_DEFFERED_DELETION ? If you dont remember we had some problems with object destroying inside their events. Because of that we are using postponed object destroying. If your new code will work with this feel free to commit it.

Yes, I remember that, that's because I was sceptic when started with changes about deffered deletion.
1.Only two objects have problems with postponed destroying TQtTimer & TQtMenu (TPopupMenu exactly).
Those objects have problems cause inside their events we call LCL directly. 2.Another one which could be problematic (theoreticaly) is TQtComboBox with call to IntfGetItems inside it's event filter. But at this moment my tests say that it does not raise any problem.

Now I'm sure that this is the right way, because it really works better and faster (apps & ide).
I'll commit it with USE_QT_44 ifdef.

zeljko

Reply by email

Paul Ishenin
to zeljko
zeljko wrote
I'll commit it with USE_QT_44 ifdef.

You want to commit even with problems with Timer and PopupMenu?

What about this code:

[code]
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
   Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics,
Dialogs,
   StdCtrls, LMessages, LCLIntf;
type
   TForm1 = class(TForm)
     Button1: TButton;
     procedure Button1Click(Sender: TObject);
   private
     procedure LM_USER1(var Message: TLMessage); message LM_USER + 1;
   public
     { public declarations }
   end;
var
   Form1: TForm1;
implementation
procedure TForm1.Button1Click(Sender: TObject);
begin
   PostMessage(Handle, LM_USER + 1, 0, 0);
end;
procedure TForm1.LM_USER1(var Message: TLMessage);
begin
   Button1.Free;
end;
initialization
   {$I unit1.lrs}
end.
[/code]

On windows this works. Will it work on qt after your changes (did not test current version).

Best regards,
Paul Ishenin.

Reply by email

zeljko
to Paul Ishenin
Paul Ishenin wrote 42 lines
zeljko wrote: > I'll commit it with USE_QT_44 ifdef. You want to commit even with problems with Timer and PopupMenu? What about this code: [code] unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, LMessages, LCLIntf; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private procedure LM_USER1(var Message: TLMessage); message LM_USER + 1; public { public declarations } end; var Form1: TForm1; implementation procedure TForm1.Button1Click(Sender: TObject); begin PostMessage(Handle, LM_USER + 1, 0, 0); end; procedure TForm1.LM_USER1(var Message: TLMessage); begin Button1.Free; end; initialization {$I unit1.lrs} end. [/code] On windows this works. Will it work on qt after your changes (did not test current version).

It works.

Reply by email