[PyKDE] weird PyQt bug: memory corruption?

Phil Thompson phil at riverbankcomputing.co.uk
Thu Apr 28 23:24:25 BST 2005


On Thursday 28 April 2005 2:18 pm, Giovanni Bajo wrote:
> Ümit Öztosun <umit.oztosun at gmail.com> wrote:
> >> What happens in my full application is an AttributeError while trying to
> >> call QScrollView.viewport().setBackgroundMode, because the name does not
> >> exit (the object is a QObject instead of a QWidget).
> >
> > Hi,
> >
> > Although I am unable to reproduce the problem, a while ago I had
> > similar problems. I was getting AttributeErrors in a QTable derived
> > custom widget. For example code similar to:
> >
> > self.verticalHeader().setResizeEnabled(False, 0)
> >
> > in that QTable derived widget sometimes failed with AttributeErrors.
> > When I examined self.verticalHeader(), I found that it was a QObject
> > instead of QHeader.
>
> Yes, this is exactly the same problem, but in a different context.
>
> > However, this occurred rarely, and dissappeared
> > after I changed the way I use queryList().
> >
> > Prior to PyQt 3.14.1 (including PyQt 3.14) this problem never
> > occurred. I observed it only in PyQt 3.14.1 and later snapshots.
> > Although I tried, I couldn't produce a sample script which
> > demonstrates the problem.
>
> This could in fact be related to queryList() somehow. Notice that queryList
> was first modified in PyQt 3.14 to add support for Python types. Also,
> queryList() was recently modified for a bugfix (it was leaking objects),
> which might be the change which hides this bug in the current PyQt
> snapshot.

Ok, I've got my finger out and debugged Giovanni's reported problem in PyQt 
v3.14.1 and SIP v4.2.1.

The bug *is* the queryList() bug - its fix is not hiding something else.

The leaked objects are still in SIP's internal map of Python objects and 
corresponding C++ addresses - and the C++ addresses may no longer be valid.

If an address is reused then SIP will find it in the map and return the 
existing Python object (probably with the wrong type) rather than create a 
new Python object (with the right type).

If the address has not been re-used (ie. it still points to the same C++ 
instance) and its type is an internal sub-class of a Qt class (ie. SIP 
doesn't recognise it) then it will fallback to QObject in queryList(). 
However the same thing would fallback to QWidget in the case of 
QScrollView.viewport().

When the test script outputs QWidget and QObject alternatively, the QWidget is 
the definately the first category because the actual type was QWidget in 
queryList() and QViewportWidget in viewport(). It is coincidence that 
viewport() returned the correct type.

The actual type at the QObject address was QViewportWidget (which SIP doesn't 
know about) both in queryList() and viewport(). So it may be either category, 
but I suspect it is the second.

They repeat because the Windows memory allocator is reusing the memory.

Phil




More information about the PyQt mailing list