On Saturday 22 April 2006 11:19 pm, Simon Edwards wrote: > On Saturday 22 April 2006 21:17, Phil Thompson wrote: > > On Saturday 22 April 2006 4:04 pm, Simon Edwards wrote: > > > I'm confused as to what the newer exec_loop() code in QDialog was meant > > > to do. > > > --------------------------------- > > > %If (Qt_3_0_0 -) > > > int exec() /PyName=exec_loop, ReleaseGIL, > > > PreHook=__pyQtPreEventLoopHook__, > > > PostHook=__pyQtPostEventLoopHook__/; > > > > > > It looks like it is meant to take ownership away from the parent dialog > > and > > > > let Python handle destruction of the popup. But the dumpObjectTree() > > > lines in my test code say that the parent dialog always keeps the popup > > > on it's list of children objects. > > > > Correct. > > > > > When the parent dialog is destroyed so are the children objects. This > > > is a problem if Python thinks that it should destroy the popup too. > > > > It's not a problem because QObject's dtor does the right thing in taking > > itself out of any parent's list of children. In other words, it doesn't > > matter (in the case of QObject and its subclasses) if both Python and C++ > > think they should call the dtor. > > I think I follow what you are saying. But that is only going to work > correctly in the case of Python and Qt wanting to destroy the child dialog > if Python calls the d'tor first. If the child dialog is destroyed by Qt > when the parent dialog is destroyed, and THEN Python comes along later > wanting to destroy the child dialog again, then it goes wrong.
This shouldn't matter. The "generated derived class" that SIP creates (sipKDialogBase in the output below) contains a dtor that will be invoked when the parent destroys it's children. It resets the pointer to the C++ instance in the Python object (see sip_api_common_dtor() in siplib.c) so that when the Python object gets garbage collected it knows the C++ instance has already been destroyed and doesn't try and do it again. Phil > valgrind output suggests that this is what is happening. The parent dialog > is destroyed. The child dialog is destroyed at the same time. And then > Python tries the child again. valgrind says that the illegal free/delete is > coming from Python itself. (the first stack trace below) And is refering to > memory that was free'd via Qt (the second stack trace). > > --------------------------------------------------- > Double QObject deletion detected. > ==7997== > ==7997== Invalid free() / delete / delete[] > ==7997== at 0x401D268: operator delete(void*) (vg_replace_malloc.c:246) > ==7997== by 0x4E22609: QObject::~QObject() (in > /usr/lib/libqt-mt.so.3.3.6) ==7997== by 0x608452A: (within > /usr/lib/python2.4/site-packages/kdeui.so) ==7997== by 0x402A927: > (within /usr/lib/python2.4/site-packages/sip.so) ==7997== by 0x8089DDF: > (within /usr/bin/python2.4) > ==7997== by 0x80FA46D: (within /usr/bin/python2.4) > ==7997== by 0x80B6FF5: PyEval_EvalFrame (in /usr/bin/python2.4) > ==7997== by 0x80B76BE: PyEval_EvalCodeEx (in /usr/bin/python2.4) > ==7997== by 0x80B7904: PyEval_EvalCode (in /usr/bin/python2.4) > ==7997== by 0x80D946B: PyRun_FileExFlags (in /usr/bin/python2.4) > ==7997== by 0x80D970B: PyRun_SimpleFileExFlags (in /usr/bin/python2.4) > ==7997== by 0x8055B02: Py_Main (in /usr/bin/python2.4) > ==7997== by 0x4080EA1: __libc_start_main > (in /lib/tls/i686/cmov/libc-2.3.6.so) > > > ==7997== Address 0x56CFFE0 is 0 bytes inside a block of size 2,044 free'd > ==7997== at 0x401D268: operator delete(void*) (vg_replace_malloc.c:246) > ==7997== by 0x6073D6B: sipKDialogBase::~sipKDialogBase() > (in /usr/lib/python2.4/site-packages/kdeui.so) > ==7997== by 0x608452A: (within > /usr/lib/python2.4/site-packages/kdeui.so) ==7997== by 0x402A927: > (within /usr/lib/python2.4/site-packages/sip.so) ==7997== by 0x8089DDF: > (within /usr/bin/python2.4) > ==7997== by 0x80FC987: (within /usr/bin/python2.4) > ==7997== by 0x4029030: (within /usr/lib/python2.4/site-packages/sip.so) > ==7997== by 0x607840C: sipKDialogBase::removeChild(QObject*) > (in /usr/lib/python2.4/site-packages/kdeui.so) > ==7997== by 0x4E22AA8: QObject::~QObject() (in > /usr/lib/libqt-mt.so.3.3.6) ==7997== by 0x4E5D05C: QWidget::~QWidget() > (in /usr/lib/libqt-mt.so.3.3.6) ==7997== by 0x4FD7A07: > QDialog::~QDialog() (in /usr/lib/libqt-mt.so.3.3.6) ==7997== by > 0x4916B05: sipQDialog::~sipQDialog() > (in /usr/lib/python2.4/site-packages/qt.so) > ==7997== by 0x491DF56: (within /usr/lib/python2.4/site-packages/qt.so) > ==7997== by 0x402A927: (within /usr/lib/python2.4/site-packages/sip.so) > ==7997== by 0x8089DDF: (within /usr/bin/python2.4) > ==7997== by 0x807A2D4: (within /usr/bin/python2.4) > ==7997== by 0x402A8A4: (within /usr/lib/python2.4/site-packages/sip.so) > ==7997== by 0x402A8E0: (within /usr/lib/python2.4/site-packages/sip.so) > ==7997== by 0x8089DDF: (within /usr/bin/python2.4) > ==7997== by 0x80FA46D: (within /usr/bin/python2.4) > ==7997== by 0x80B6FF5: PyEval_EvalFrame (in /usr/bin/python2.4) > ==7997== by 0x80B76BE: PyEval_EvalCodeEx (in /usr/bin/python2.4) > ==7997== by 0x80B7904: PyEval_EvalCode (in /usr/bin/python2.4) > ==7997== by 0x80D946B: PyRun_FileExFlags (in /usr/bin/python2.4) > ==7997== by 0x80D970B: PyRun_SimpleFileExFlags (in /usr/bin/python2.4) > ==7997== by 0x8055B02: Py_Main (in /usr/bin/python2.4) > ==7997== by 0x4080EA1: __libc_start_main > (in /lib/tls/i686/cmov/libc-2.3.6.so) > --------------------------------------------------- _______________________________________________ PyKDE mailing list PyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde