backend dies when C function calls C++ library that throws an exception - Mailing list pgsql-hackers

From David Blasby
Subject backend dies when C function calls C++ library that throws an exception
Date
Msg-id 3E974DDB.8060000@refractions.net
Whole thread Raw
Responses Re: backend dies when C function calls C++ library that throws an exception  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
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



pgsql-hackers by date:

Previous
From: Greg Stark
Date:
Subject: Re: [GENERAL] medical image on postgreSQL?
Next
From: Sean Chittenden
Date:
Subject: Re: [GENERAL] medical image on postgreSQL?