Opened 17 years ago

Closed 17 years ago

Last modified 17 years ago

#1756 closed defect (fixed)

CreateDataSource segfaults in some cases

Reported by: Ari Jolma Owned by: Mateusz Łoskot
Priority: highest Milestone:
Component: OGR_SF Version: unspecified
Severity: normal Keywords: shapefile
Cc: warmerdam

Description

Code

use Geo::GDAL;
$driver = Geo::OGR::GetDriverByName('ESRI Shapefile');
$datasource = $driver->CreateDataSource('.');

causes a segfault if there is a read-only shapefile in directory '.'. I have not tested with other drivers.

Attachments (1)

test.cpp (667 bytes ) - added by Mateusz Łoskot 17 years ago.
Simple test program in C reproducing the problem

Download all attachments as: .zip

Change History (13)

comment:1 by warmerdam, 17 years ago

Cc: warmerdam added
Keywords: shapefile added
Owner: changed from warmerdam to Mateusz Łoskot

Mateusz,

Could you look into this?

comment:2 by Mateusz Łoskot, 17 years ago

Priority: normalhighest
Status: newassigned

comment:3 by Mateusz Łoskot, 17 years ago

Ari,

I think I need more details. What does the CreateDataSource() function do? Does it open existing datasource or create a new one?

I did a short test with ogrinfo and it seems that read-only shapefiles in a directory are not detected as layers at all, a little strange indeed, but no segmentation fault occurs.

  • Directory with two Shapefiles and all files have 0644 perms:
mloskot@dog:~/dev/gdal/bugs/1756$ ls -l
total 44
-rw-r--r-- 1 mloskot mloskot  3988 2007-08-22 16:03 point.dbf
-rw-r--r-- 1 mloskot mloskot   143 2007-08-22 16:03 point.prj
-rw-r--r-- 1 mloskot mloskot  1584 2007-08-22 16:03 point.shp
-rw-r--r-- 1 mloskot mloskot   524 2007-08-22 16:03 point.shx
-rw-r--r-- 1 mloskot mloskot    74 2007-08-22 16:03 poly.dbf
-rw-r--r-- 1 mloskot mloskot   143 2007-08-22 16:03 poly.prj
-rw-r--r-- 1 mloskot mloskot 14940 2007-08-22 16:03 poly.shp
-rw-r--r-- 1 mloskot mloskot   108 2007-08-22 16:03 poly.shx

and test with ogrinfo:

mloskot@dog:~/dev/gdal/bugs/1756$ ogrinfo .
OGR: OGROpen(./0x804c998) succeeded as ESRI Shapefile.
INFO: Open of `.'
      using driver `ESRI Shapefile' successful.
OGR: GetLayerCount() = 2

1: point (Point)
2: poly (Polygon)
  • The same directory but files of Polygon layer are read-only with 0444 perms:
mloskot@dog:~/dev/gdal/bugs/1756$ chmod 0444 poly.*
mloskot@dog:~/dev/gdal/bugs/1756$ ls -l
total 44
-rw-r--r-- 1 mloskot mloskot  3988 2007-08-22 16:03 point.dbf
-rw-r--r-- 1 mloskot mloskot   143 2007-08-22 16:03 point.prj
-rw-r--r-- 1 mloskot mloskot  1584 2007-08-22 16:03 point.shp
-rw-r--r-- 1 mloskot mloskot   524 2007-08-22 16:03 point.shx
-r--r--r-- 1 mloskot mloskot    74 2007-08-22 16:03 poly.dbf
-r--r--r-- 1 mloskot mloskot   143 2007-08-22 16:03 poly.prj
-r--r--r-- 1 mloskot mloskot 14940 2007-08-22 16:03 poly.shp
-r--r--r-- 1 mloskot mloskot   108 2007-08-22 16:03 poly.shx

and ogrinfo says:

mloskot@dog:~/dev/gdal/bugs/1756$ ogrinfo .
ERROR 4: Unable to open ./poly.shp or ./poly.SHP.
OGR: OGROpen(./0x804c998) succeeded as ESRI Shapefile.
INFO: Open of `.'
      using driver `ESRI Shapefile' successful.
OGR: GetLayerCount() = 1

1: point (Point)

ogrinfo notifies with error message but no segmentation fault occurs.

Anyway, it's obvious there is something wrong with opening read-only layers, so I'm investigating it.

comment:4 by Mateusz Łoskot, 17 years ago

Ah, I've forgot to add something important here :-)

The ogrinfo tries to open layer in update mode by default (r+ for Shapefile) and if you use -ro switch, then everything works well:

loskot@dog:~/dev/gdal/bugs/1756$ ogrinfo -ro .
OGR: OGROpen(./0x804c998) succeeded as ESRI Shapefile.
INFO: Open of `.'
      using driver `ESRI Shapefile' successful.
OGR: GetLayerCount() = 2

1: point (Point)
2: poly (Polygon)

I tested GDAL from current SVN trunk.

Ari,

Perhaps, there is something wrong with Perl bindings like layer pointer is not tested against NULL?

comment:5 by Ari Jolma, 17 years ago

this is the backtrace from linux (I run the code in a dir with ro shapefiles):

#0  0x010dbba9 in OGRDataSource::SetDriver () from /usr/local/lib/libgdal.so.1
#1  0x01101d91 in OGR_Dr_CreateDataSource () from /usr/local/lib/libgdal.so.1
#2  0x0077b686 in _wrap_Driver_CreateDataSource (my_perl=0x9bbf008, 
    cv=0x9cf653c) at ogr_wrap.cpp:1613

The poDriver is NULL I guess in line 74 of ogrsdriver.cpp. Hmm, but poDriver is hDriver, which should come from the wrapper (it is the object, whose method is called ... but it can't be null since its method is found... eeh)

Ari

by Mateusz Łoskot, 17 years ago

Attachment: test.cpp added

Simple test program in C reproducing the problem

comment:6 by Mateusz Łoskot, 17 years ago

I finally reproduced the problem with the test.cpp program. The assert caught in OGR C API call OGR_Dr_CreateDataSource() caused the driver pointer is not set properly.

mloskot@dog:~/dev/gdal/bugs/1756$ ./test 
CraeteDataSource( ./ro )
ERROR 4: Unable to open ./ro/poly.shp or ./ro/poly.SHP.
ERROR 4: Failed to open shapefile ./ro/poly.shp.
It may be corrupt.

ERROR 7: Assertion `NULL != poDS' failed
in file `ogrsfdriver.cpp', line 73

Aborted (core dumped)

Fixing.

comment:7 by Mateusz Łoskot, 17 years ago

Ari,

I fixed GDAL and I'm ready to test before committing, but I'm having troubles with running my Perl scripts using GDAL.

  • Is there any way to run Perl scripts without calling make install for GDAL?

I build GDAL without libtool and I run test programs without calling make install for GDAL, so I don't have libgdal.so in /usr/lib or any other standard location. I just set LD_LIBRARY_PATH to point my custom location I use for development.

I tried to call make test inside swig/perl, after make build, but it fails with following error:

#   Failed test 'use Geo::GDAL;'
#   in t/ogr.t at line 2.
#     Tried to use 'Geo::GDAL'.
#     Error:  Can't load '/home/mloskot/dev/gdal/_svn/trunk/gdal/swig/perl/blib/arch/auto/Geo/GDAL/Const/Const.so' for module Geo::GDAL::Const: libgdal1.3.2.so.1: cannot open shared object file: No such file or directory at /usr/lib/perl/5.8/DynaLoader.pm line 225.
#  at /home/mloskot/dev/gdal/_svn/trunk/gdal/swig/perl/blib/lib/Geo/GDAL/Const.pm line 11

It looks like it's expecting to find libgdal1.3.2.so.1 but I don't use this library. I want the bindings to link against to libgdal.so inside my custom location pointed in LD_LIBRARY_PATH.

Any idea?

comment:8 by Ari Jolma, 17 years ago

Mateusz,

Could you issue "ln -s libgdal.so libgdal1.3.2.so.1" in your dev dir?

If I remove libgdal.so from known locations and issue

"export LD_LIBRARY_PATH=/home/ajolma/gdal/.libs/"

make test works. To use your own test code just put it into t/ as something like t/test.t and possibly remove other *.t scripts.

comment:9 by Mateusz Łoskot, 17 years ago

Ari,

Thanks for the trick. Yes, it works for me now:

mloskot@dog:~/dev/gdal/_svn/trunk/gdal$ ls -l libgdal*
lrwxrwxrwx 1 mloskot mloskot       10 2007-08-22 21:15 libgdal1.3.2.so.1 -> libgdal.so
-rw-r--r-- 1 mloskot mloskot 24298626 2007-08-22 22:30 libgdal.a
-rwxr-xr-x 1 mloskot mloskot 19093411 2007-08-22 22:30 libgdal.so

I have one additional question. Do Perl bindings affect env like CPL_DEBUG? I added some CPLDebug() calls to the OGR_Dr_CreateDataSource() function, I have exported CPL_DEBUG=ON, but I don't get any messages printed out:

mloskot@dog:~/dev/gdal/_svn/trunk/gdal$ echo $CPL_DEBUG 
ON
mloskot@dog:~/dev/gdal/_svn/trunk/gdal$ perl test.pl
RuntimeError Failed to open shapefile ro/poly.shp.
It may be corrupt.

mloskot@dog:~/dev/gdal/_svn/trunk/gdal$ 

If I replace CPLDebug() with regular printf(), I get my messages printed. The same problem is with CPLAssert - nothing is printed from GDAL when used through Perl bindings.

Anyway, I applied some fix to the OGR_Dr_CreateDataSource and now no segfault occurs when trying to call CreateDataSource on directory with read-only shapefiles:

mloskot@dog:~/dev/gdal/_svn/trunk/gdal$ ls -l ro
total 28
-r--r--r-- 1 mloskot mloskot    74 2007-08-22 21:51 poly.dbf
-r--r--r-- 1 mloskot mloskot   143 2007-08-22 21:51 poly.prj
-r--r--r-- 1 mloskot mloskot 14940 2007-08-22 21:51 poly.shp
-r--r--r-- 1 mloskot mloskot   108 2007-08-22 21:51 poly.shx

mloskot@dog:~/dev/gdal/_svn/trunk/gdal$ cat ./test.pl
use Geo::GDAL;
$driver = Geo::OGR::GetDriverByName('ESRI Shapefile');
$datasource = $driver->CreateDataSource('ro');

mloskot@dog:~/dev/gdal/_svn/trunk/gdal$ perl ./test.pl
RuntimeError Failed to open shapefile ro/poly.shp.
It may be corrupt or read-only file accessed in update mode.

As you see, RuntimeError is thrown and the updated message suggests possible problem.

I'm committing my patch in a few minutes.

comment:10 by Mateusz Łoskot, 17 years ago

Resolution: fixed
Status: assignedclosed

The patch has been applied (r11928).

Ari,

As you can see in the patch, I added extra CPLDebug() call warning about NULL pointer returned (ogrsfdriver.cpp:83). When I export CPL_DEBUG=ON and then use Perl script like yours and the OGR_Dr_CreateDataSource() function fails, this message is not printed at all.

I'm going to close this ticket. Please, reopen it if the problem is still there.

in reply to:  10 comment:11 by Ari Jolma, 17 years ago

When I export CPL_DEBUG=ON and then use Perl script like yours and the OGR_Dr_CreateDataSource() function fails, this message is not printed at all.

It's because the bindings (at least Perl seemingly, I don't know about others) have somehow called UseExceptions() thus setting VeryQuiteErrorHandler. Put

Geo::GDAL::DontUseExceptions;

into your code and you'll see the debug messages. (this was news to me too)

comment:12 by Mateusz Łoskot, 17 years ago

Ari,

Understood. Thanks.

Note: See TracTickets for help on using tickets.