Dear Nathan,

OK, things get clearer now : looks like my thought were right.
Now, knowing all of this I still have a goal in mind : develop
production (24/24 availability) ready application  with Qt.
To achieve that, I may very careful with ownership issues, that's the
first thing one could do. Howver, being an old  (:-)) developper, I know
all the tricks and how Murphy's always around the corner. So
my next logical step is : how could I have PySide/Python/valgrind, etc. look out
automatically for wrong or potentially wrong situations...

I thought about this last night. Here's the gist of it :

The ownership problem is really dangerous when a Python object that was passed
to PySide is ready for garbage collection (ref count 0) and if that object
is still necessary for PySide. The first part (ref count = 0) is easy to get I
think (never done that but I bet Python's has some stuff to do that, I could 
even hack
something if needed). The other part is harder : how to know if a PySide object
still has a potential need for an object. To answer that question, there's only 
one
way : have a description of the behaviour of the object (or its class). Since
this is basically impossible to achieve, I think I need some heuristic or 
simplification.

On thing I certainly can say, is that I don't use 100% of PySide. Say 2 dozens 
classes
and maybe a hundred methods. So I could track what happens there manually. 
Basically, I could
say that if an object X was passed to one of these PySide object (call it Q) , 
then I
can assume PySide/Qt will need it as long as Q is alive. So if X gets ready for 
GC
and Q is not itself ready for GC, then we may end up in troubles. That may be a 
false
positive but at least, that's worth investigating.

So what I need now is to write such a tracking mechanism.. I'll look at it 
(unless
somebody already went that road :-)). I'll see if it is practical or not. I'll 
also
have a look at the debug mode of Shiboken, seems easy to turn on. Maybe there 
are
already useful things built in.

Besides, I've tried valgrind last night as well. I built a Python with 
--with-valgrind
for that and rebuild PySide accordingly. Worked like a charm. Valgrind returned
a handfull of possible crash things (if I got it correctly, never used valgrind 
before).
However, I saw there are several memory leaks happening around initQtCore and 
initQtGui
in module imports. Well that's what valgrind says. Since it's in the import 
stuff
it may just be that PySide doesn't clean up everything on exit; that may just 
be fine.

I hope to get some results soon...

Again thank you for providing so much information, it just helps so much to 
have my
thoughts validated.

Stefan



On Sat, Jan 14, 2012 at 03:59:11PM -0600, Nathan Smith wrote:


> You are correct.  Because renderer does not take ownership of the Source()
> object, its reference count is decremented to 0 after the first line.  When 
> the
> reference count hits 0, the object may be reaped by the garbage collector.
>  However, some garbage collectors (not sure about Python's) use delayed
> collection to improve performance.  That is, they don't reap objects available
> for reaping immediately, but accumulate them and then will delete them at some
> point in the future.  So, renderer.render() may execute correctly and Valgrind
> may detect access to a region of memory that has been deallocated.  
>
> To further complicate things, it is possible that the code you posted may
> appear to execute correctly even if the Source object is deleted.  This could
> happen if no new memory is allocated on top of where Source was allocated, if 
> a
> new Source object is allocated in the same memory location that the old Source
> object was allocated, or if a new object of a different type is allocated that
> overlaps the old Source object but just so happens to have memory values that
> work for Source.  All of these are reasons why debugging dangling pointer
> problems is so difficult.  Valgrind will catch most problems if the 
> application
> is sufficiently complicated and runs long enough.  I'm not sure if Valgrind is
> sophisticated enough to detect dangling pointers that are not referenced
> (though I suspect it is not).
>
> Nathan
>
> On Sat, Jan 14, 2012 at 3:44 PM, S. Champailler <[email protected]> 
> wrote:
>      After a bit of reading, I still don't get this. In the doc, I see
>      that his code is wrong :
>
>            renderer.setModel(Source())
>            renderer.render()
>
>      because the Source() object will be destroyed too soon. That makes
>      sense.
>
>      What I don't get is &quot;how wrong&quot; it is. That is, if the
>      Python Source() object is destroyed by Python, then does it mean that
>      the reference that is still present in the renderer is wrong (i.e. it
>      has a pointer to some memory that was freed and that may blow up as
>      soon as renderer tries to reference that ememory) ?
>      I don't see any other explanation, but I want to be sure. If it's
>      because of that then is there somebody who has some experience in
>      debugging that ? I've set up valgrind but I'm not sure it will bring
>      in systematic result. After all, if &quot;renderer&quot; never uses
>      the dangling pointer, then valgrind will never see anything wrong...
>
>      Am I right (this would save me some frustration :-))
>
>      Stefan
>
>
>
>
>      > Well,
>      >
>      > Not that I have figured out how to fix my code, but I did find out
>      the documentation that explains that in *great* details (and in a
>      rather clear way). It's there for those who are still looking for :
>      >
>      > pyside/shiboken/doc/ownership.rst
>      >
>      > I'm a little bit ashamed of not finding this earlier
>      >
>      > stF
>      >
>      >
>      > On Mon, Jan 09, 2012 at 10:36:32PM +0100, S. Champailler wrote:
>      > > Dear mailing list,
>      > >
>      > > In my python code, I usually create QStandardItem with some data,
>      but now I realize it may be plain wrong :
>      > >
>      > >
>      > > def make_simple_model(my_data)
>      > >    model = QtGui.QStandardItemModel(1, 1)
>      > >
>      > >    item = QtGui.QStandardItem()
>      > >    item.setData(my_data, Qt.UserRole)
>      > >    model.setItem(0, 0, item) # Model takes ownership of the Item
>      (if I understand Qt's doc well)
>      > >
>      > >    return model
>      > >
>      > > my_data = ... # some kind of Python object
>      > > model = make_simple_model(my_data)
>      > >
>      > > # After this, Python has lost track of my data
>      > > my_data = None
>      > >
>      > > # This one is correct, because model is still tracked by Python
>      and the item is owned by the model
>      > > item = model.item(0,0)
>      > >
>      > > # But this is dangerous (because the data has been lost)
>      > > item.data( Qt.UserRole)
>      > >
>      > >
>      > >
>      > > If I got the &quot;PySide pitfalls&quot; page well, this code is
>      wrong : my_data got lost (last line of the code) and therefore, the
>      QStandardItem UserRole data is a dangling p\
>      > > ointer...
>      > >
>      > > Is my interpretation correct ? If so, I'd be happy to add this to
>      the &quot;pitfalls&quot; page. Although that page does explain the
>      issue, somehow, I thought this code was cor\
>      > > rect until now (it worked thousands of times) => maybe other
>      developpers may have the same misunderstanding.
>      > >
>      > > Thx,
>      > >
>      > > Stefan
>      > >
>      > >
>      > >
>      > > _______________________________________________
>      > > PySide mailing list
>      > > [email protected]
>      > > http://lists.pyside.org/listinfo/pyside
>      > _______________________________________________
>      > PySide mailing list
>      > [email protected]
>      > http://lists.pyside.org/listinfo/pyside
>      _______________________________________________
>      PySide mailing list
>      [email protected]
>      http://lists.pyside.org/listinfo/pyside
>

> _______________________________________________
> PySide mailing list
> [email protected]
> http://lists.pyside.org/listinfo/pyside

_______________________________________________
PySide mailing list
[email protected]
http://lists.pyside.org/listinfo/pyside

Reply via email to