backend dies when C function calls C++ library that throws an exception

From: David Blasby <dblasby(at)refractions(dot)net>
To: pgsql-hackers(at)postgresql(dot)org
Subject: backend dies when C function calls C++ library that throws an exception
Date: 2003-04-11 23:20:59
Message-ID: 3E974DDB.8060000@refractions.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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(at)refractions(dot)net

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Sean Chittenden 2003-04-11 23:43:56 Re: [GENERAL] medical image on postgreSQL?
Previous Message Greg Stark 2003-04-11 23:06:03 Re: [GENERAL] medical image on postgreSQL?