Opened 16 years ago

Closed 15 years ago

#2246 closed defect (worksforme)

segfault on Feature introspection

Reported by: brentp Owned by: hobu
Priority: normal Milestone:
Component: PythonBindings Version: svn-trunk
Severity: normal Keywords: python feature
Cc:

Description

$ gdalinfo --version GDAL 1.6.0dev, released 2008/00/00

python version Out[3]: <module 'osgeo.ogr' from '/usr/lib/python2.5/site-packages/GDAL-1.5.0-py2.5-linux-i686.egg/osgeo/ogr.pyc'>

the code below creates a segfault.

from osgeo import ogr
m = ogr.GetDriverByName('memory')
ds = m.CreateDataSource('t')
l = ds.CreateLayer('', geom_type=ogr.wkbPoint)
f = ogr.Feature(feature_def=l.GetLayerDefn())

f # ok

# ok to use existing method
f.SetGeometryDirectly(ogr.CreateGeometryFromWkt('Point(2 2)'))

# introspection segfaults.
#dir(f)

# non existant property/method segfaults
f.a

trying to access a non-existent property/method, or calling dir() on a feature will cause a segfault. this is true also for features from an existing data source and

Change History (5)

comment:1 by Even Rouault, 16 years ago

I can't reproduce any crash. I get the expected behaviour :

>>> f.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.5/site-packages/osgeo/ogr.py", line 1829, in __getattr__
    raise AttributeError, name
AttributeError: a

comment:2 by Even Rouault, 16 years ago

But... the following slightly modified version gives a segfault :

#!/usr/bin/env python

from osgeo import ogr
m = ogr.GetDriverByName('memory')
ds = m.CreateDataSource('t')
l = ds.CreateLayer('', geom_type=ogr.wkbPoint)
f = ogr.Feature(feature_def=l.GetLayerDefn())
geom = ogr.CreateGeometryFromWkt('Point(2 2)')
f.SetGeometryDirectly(geom)
f.SetGeometryDirectly(geom)

Valgrind output :

==21009== Invalid read of size 4
==21009==    at 0x4A7EEE2: OGRFeature::~OGRFeature() (ogrfeature.cpp:115)
==21009==    by 0x4A7A722: OGR_F_Destroy (ogrfeature.cpp:178)
==21009==    by 0x4428D9E: _wrap_delete_Feature (ogr_wrap.cpp:3078)
==21009==    by 0x8061073: PyObject_CallFunctionObjArgs (in /usr/bin/python2.5)
==21009==    by 0x4420336: PySwigObject_dealloc (ogr_wrap.cpp:1440)
==21009==    by 0x8086BEE: (within /usr/bin/python2.5)
==21009==    by 0x809BFDD: (within /usr/bin/python2.5)
==21009==    by 0x80855F8: (within /usr/bin/python2.5)
==21009==    by 0x8086F5D: PyDict_SetItem (in /usr/bin/python2.5)
==21009==    by 0x8088BB7: _PyModule_Clear (in /usr/bin/python2.5)
==21009==    by 0x80DD0E2: PyImport_Cleanup (in /usr/bin/python2.5)
==21009==    by 0x80E931E: Py_Finalize (in /usr/bin/python2.5)
==21009==  Address 0x6CCA180 is 0 bytes inside a block of size 36 free'd
==21009==    at 0x4022096: operator delete(void*) (vg_replace_malloc.c:244)
==21009==    by 0x4A6D902: OGRPoint::~OGRPoint() (ogrpoint.cpp:87)
==21009==    by 0x4A7A76D: OGRFeature::SetGeometryDirectly(OGRGeometry*) (ogrfeature.cpp:292)
==21009==    by 0x4A7B2A9: OGR_F_SetGeometryDirectly (ogrfeature.cpp:328)
==21009==    by 0x44288A1: _wrap_Feature_SetGeometryDirectly (ogr_wrap.cpp:3090)
==21009==    by 0x805C9E6: PyObject_Call (in /usr/bin/python2.5)
==21009==    by 0x80C709E: PyEval_EvalFrameEx (in /usr/bin/python2.5)
==21009==    by 0x80CA114: PyEval_EvalCodeEx (in /usr/bin/python2.5)
==21009==    by 0x80C85D8: PyEval_EvalFrameEx (in /usr/bin/python2.5)
==21009==    by 0x80CA114: PyEval_EvalCodeEx (in /usr/bin/python2.5)
==21009==    by 0x80CA186: PyEval_EvalCode (in /usr/bin/python2.5)
==21009==    by 0x80E9697: PyRun_FileExFlags (in /usr/bin/python2.5)

in reply to:  1 comment:3 by brentp, 16 years ago

hi, i checked on other machines and was unable to reproduce this. i rebuilt gdal, and the python bindings twice on the machine that had the problem and still got the behavior i reported above. if i clear out my site-packages, and easy-install.pth and use the GDAL package on pypi, then it works fine.

also, using GDAL from pypy, i get no segfault from roalt's case above:


In [2]: from osgeo import ogr

In [3]: m = ogr.GetDriverByName('memory')

In [4]: ds = m.CreateDataSource('t')

In [5]: l = ds.CreateLayer('', geom_type=ogr.wkbPoint)

In [6]: f = ogr.Feature(feature_def=l.GetLayerDefn())

In [7]: geom = ogr.CreateGeometryFromWkt('Point(2 2)')

In [8]: f.SetGeometryDirectly(geom)

Out[8]: 0

In [9]: f.SetGeometryDirectly(geom)

Out[9]: 0

comment:4 by Even Rouault, 16 years ago

In fact, the second 'f.SetGeometryDirectly(geom)' is probably not enough to make python crash. However, with Valgrind, you will notice the error I reported. A third or fourth 'f.SetGeometryDirectly(geom)' will cause the crash anyway.

comment:5 by hobu, 15 years ago

Resolution: worksforme
Status: newclosed

I'm going to chalk this one up to a Heisenbug, but I will say that

f.SetGeometryDirectly(ogr.CreateGeometryFromWkt('Point(2 2)'))

is a bad practice because the reference to the geometry is going to be gone by the time SetGeometryDirectly goes to set it. Still in memory, and maybe not yet deleted, but you need to keep a reference to that geometry around until after SetGeoemtryDirectly happens. If it works any other way, you're just getting lucky.

g = ogr.CreateGeometryFromWkt('Point(2 2)')
f.SetGeometryDirectly(g)
Note: See TracTickets for help on using tickets.