PostGIS (open source spatial objects for postgresql -
http://postgis.refractions.net ) is trying to integrate a C++ geometry
package (GEOS - Geometry Engine, Open Source -
http://geos.refractions.net ).
We are having trouble trapping exceptions thrown by the GEOS C++
library. The library isworking very well in general, but when GEOS
raises an exception that tries to leave the GEOS .so library, postgresql
immediately dies (signal 6 - ABORT).
The postgis library is a set of custom functions that are called by
postgresql using the standard API. These postgis functions call
functions in the GEOS library.
Basically, the layout is like:
postgis_geos.c -- gets merged into postgis.so which is loaded and used
by directly by postgresql.
postgis_geos_wrapper.cpp -- also merges into postgis.so, but handles
calls to the GEOS c++ library.
libgeos.so --- geos library
In postgis_geos.c ,the only interesting line is "result =
GEOSrelateOverlaps(g1,g2);" which calls a c++ wrapper function (see below).
PG_FUNCTION_INFO_V1(overlaps);
Datum overlaps(PG_FUNCTION_ARGS)
{GEOMETRY *geom1 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));GEOMETRY *geom2 = (GEOMETRY *)
PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
...
result = GEOSrelateOverlaps(g1,g2);if (result == 2){ elog(ERROR,"GEOS overlaps() threw an error!");
PG_RETURN_NULL();//never get here}
PG_RETURN_BOOL(result);
}
postgis_geos_wrapper.cpp - this also get merged into postgis.so - it
handles calling GEOS.
//extern "C" GEOSrelateContains(Geometry *g1, Geometry*g2);
char GEOSrelateContains(Geometry *g1, Geometry*g2)
{try { bool result; result = g1->contains(g2); if (result) return 1; else return 0;}catch
(...){ return 2;}
}
In general, this "wrapping" works fine - I've left out a bunch of
details, but things work *great* in postgresql as long as GEOS doesnt
throw any exceptions.
I can write stand alone C programs that handle the exceptions properly.
Its only has problems when there's three levels of indirection
(postgresql->postgis wrapper->GEOS).
If you write a C (or C++) program that uses the wrapper, everything
works fine.
Others have had similiar problems - for example people writing PERL
modules that use the perl "C" api to call C++ libraries. People doing
the same with PYTHON have also had problems. The only technical
reference I can find is at:
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=37933
Basically, there's a problem if libc is loaded before libc++ because the
exception handler isnt installed (or some such thing).
Anyone have any ideas of what to do about this?
dave blasby
dblasby@refractions.net