#9448: segfault: django.contrib.gis.gdal.DataSource sub-objects not holding
references to parents
----------------------------------------+-----------------------------------
 Reporter:  [EMAIL PROTECTED]  |       Owner:  nobody    
   Status:  new                         |   Milestone:            
Component:  GIS                         |     Version:  1.0       
 Keywords:                              |       Stage:  Unreviewed
Has_patch:  0                           |  
----------------------------------------+-----------------------------------
 GeoDjango is setting up its users for segfaults by not being careful with
 managing references in `ctypes`-based objects.  I've only personally
 encountered it with `gdal.DataSource` so far, but a glance at the code
 makes me suspect it's more rampant, given GeoDjango's extensive use of
 `ctypes`.

 Consider this toy sequence:

 {{{
 def get_layer(id=0):
   ds = DataSource('mydataset.shp')
   return ds[id]

 layer = get_layer()
 print layer.num_feat
 }}}

 This innocent-looking snippet will crash Python hard.  The problem is that
 the layer object that is returned by `ds[id]` does not hold a reference
 back to the `ds` object, which in turn is holding the only reference to
 the underlying `ctypes` object.  The layer object only holds a glorified
 `void*`.  As soon as you try to use it after the `ds` object has gone out
 of scope, blammo.

 There are several places this could get fixed by sticking a back-reference
 into the layer object.  You could do it inside `DataSource.__getitem__`,
 though that would be a little contrived.  Better, you could create
 variants of
 ```django.contrib.gis.gdal.prototypes.generation.voidptr_output``` and
 friends that take an extra argument (the parent object) and stuff a
 reference to it into the result along with all the other stuff they're
 jamming in there.  That's probably what I would do.  Whatever solution is
 chosen, it should be general enough to make it easy to solve this problem
 in all the places it occurs.

 To sum up in a nutshell: every return value from a `ctypes`-based object
 needs to either only use '''copies''' of data, or it needs to also include
 (directly or indirectly) a reference back to the underlying `ctypes`
 object.  Otherwise you're just asking for trouble.

 Once you understand it, this is pretty easy to work around --- in this
 case you just have to hang on to an extra copy of each `DataSource` object
 as long as any of its children might continue to exist.  It is a tad
 annoying, though.

-- 
Ticket URL: <http://code.djangoproject.com/ticket/9448>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to