[postgis-tickets] [PostGIS] #3407: topology: crash when using ST_AddEdgeModFace on face that's part of multiple topogeometries

PostGIS trac at osgeo.org
Wed Dec 23 06:47:14 PST 2015


#3407: topology: crash when using ST_AddEdgeModFace on face that's part of
multiple topogeometries
----------------------+---------------------------
 Reporter:  rulus     |      Owner:  strk
     Type:  defect    |     Status:  new
 Priority:  medium    |  Milestone:  PostGIS 2.2.1
Component:  topology  |    Version:  2.2.x
 Keywords:            |
----------------------+---------------------------
 When using ST_AddEdgeModFace to add a new edge splitting a face that's
 part of more than 1 topogeometry, postgres crashes with a segfault.

 I am running version
 PostgreSQL 9.4.5 on x86_64-unknown-linux-gnu, compiled by gcc (Debian
 5.2.1-23) 5.2.1 20151028, 64-bit POSTGIS="2.2.0 r14208"
 GEOS="3.5.0-CAPI-1.9.0 r4084" PROJ="Rel. 4.9.2, 08 September 2015"
 GDAL="GDAL 2.0.1, released 2015/09/15" LIBXML="2.9.3" LIBJSON="0.11.99"
 TOPOLOGY RASTER

 Using gdb I got this backtrace:
 {{{
 Program received signal SIGSEGV, Segmentation fault.
 0x00007fd5ac1d8358 in cb_updateTopoGeomFaceSplit (topo=0x55c79d7b6ae0,
 split_face=<optimized out>, new_face1=133, new_face2=-1) at
 postgis_topology.c:2018
 2018        HeapTuple row = SPI_tuptable->vals[i];
 (gdb) bt
 #0  0x00007fd5ac1d8358 in cb_updateTopoGeomFaceSplit (topo=0x55c79d7b6ae0,
 split_face=<optimized out>, new_face1=133, new_face2=-1) at
 postgis_topology.c:2018
 #1  0x00007fd5ac201cfd in lwt_be_updateTopoGeomFaceSplit
 (topo=0x55c79d7b6b48, topo=0x55c79d7b6b48, new_face2=-1, new_face1=133,
 split_face=<optimized out>) at lwgeom_topo.c:350
 #2  _lwt_AddEdge (topo=topo at entry=0x55c79d7b6b48,
 start_node=start_node at entry=142, end_node=end_node at entry=208,
 geom=geom at entry=0x55c79d7b46f0, skipChecks=skipChecks at entry=0,
 modFace=modFace at entry=1)
     at lwgeom_topo.c:2696
 #3  0x00007fd5ac20500b in lwt_AddEdgeModFace
 (topo=topo at entry=0x55c79d7b6b48, start_node=start_node at entry=142,
 end_node=end_node at entry=208, geom=geom at entry=0x55c79d7b46f0,
 skipChecks=skipChecks at entry=0)
     at lwgeom_topo.c:2722
 #4  0x00007fd5ac1d9f20 in ST_AddEdgeModFace (fcinfo=0x55c79d7df650) at
 postgis_topology.c:3207
 #5  0x000055c79cd5ee83 in ?? ()
 #6  0x000055c79cd64e6d in ExecProject ()
 #7  0x000055c79cd77568 in ExecResult ()
 #8  0x000055c79cd5dd18 in ExecProcNode ()
 #9  0x000055c79cd5af5e in standard_ExecutorRun ()
 #10 0x000055c79cd8188f in ?? ()
 #11 0x000055c79cd81bac in SPI_execute_plan_with_paramlist ()
 #12 0x00007fd5b36094a4 in ?? () from
 /usr/lib/postgresql/9.4/lib/plpgsql.so
 #13 0x00007fd5b360d6c5 in ?? () from
 /usr/lib/postgresql/9.4/lib/plpgsql.so
 #14 0x00007fd5b360faad in ?? () from
 /usr/lib/postgresql/9.4/lib/plpgsql.so
 #15 0x00007fd5b360fcd2 in plpgsql_exec_function () from
 /usr/lib/postgresql/9.4/lib/plpgsql.so
 #16 0x00007fd5b3604d49 in plpgsql_call_handler () from
 /usr/lib/postgresql/9.4/lib/plpgsql.so
 #17 0x000055c79cd5ee83 in ?? ()
 #18 0x000055c79cd64e6d in ExecProject ()
 #19 0x000055c79cd77568 in ExecResult ()
 #20 0x000055c79cd5dd18 in ExecProcNode ()
 #21 0x000055c79cd5af5e in standard_ExecutorRun ()
 #22 0x000055c79ce55247 in ?? ()
 #23 0x000055c79ce56888 in PortalRun ()
 #24 0x000055c79ce534e3 in PostgresMain ()
 #25 0x000055c79cc1c773 in ?? ()
 #26 0x000055c79cdfd50a in PostmasterMain ()
 #27 0x000055c79cc1d90c in main ()
 }}}

 Leading me to the cb_updateTopoGeomFaceSplit function in
 topology/postgis_topology.c (I used the 2.2.0 release from the git tag).

 The problem seems to occur when the first SELECT query yields > 1 result,
 in which case {{{ntopogeoms}}} > 1 and the following loop is executed
 multiple times.

 Inside the loop the global SPI_tuptable variable is used to access the
 results from the SELECT query. However, inside the loop other INSERT
 queries are issued overwriting this SPI_tuptable variable causing the
 crash in the second iteration.

 I tried a proof-of-concept fix by saving a reference to the original
 SPI_tuptable and this seems to fix the crash and behave correctly:
 {{{
 --- a/topology/postgis_topology.c
 +++ b/topology/postgis_topology.c
 @@ -1975,6 +1975,7 @@ cb_updateTopoGeomFaceSplit ( const LWT_BE_TOPOLOGY*
 topo,
    StringInfoData sqldata;
    StringInfo sql = &sqldata;
    int i, ntopogeoms;
 +  SPITupleTable *tupTable;
    const char *proj = "r.element_id, r.topogeo_id, r.layer_id,
 r.element_type";

    POSTGIS_DEBUGF(1, "cb_updateTopoGeomFaceSplit signalled "
 @@ -2013,10 +2014,11 @@ cb_updateTopoGeomFaceSplit ( const
 LWT_BE_TOPOLOGY* topo,
    }

    ntopogeoms = SPI_processed;
 +  tupTable = SPI_tuptable;
    for ( i=0; i<ntopogeoms; ++i )
    {
 -    HeapTuple row = SPI_tuptable->vals[i];
 -    TupleDesc tdesc = SPI_tuptable->tupdesc;
 +    HeapTuple row = tupTable->vals[i];
 +    TupleDesc tdesc = tupTable->tupdesc;
      int negate;
      int element_id;
      int topogeo_id;
 }}}

--
Ticket URL: <https://trac.osgeo.org/postgis/ticket/3407>
PostGIS <http://trac.osgeo.org/postgis/>
The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project.


More information about the postgis-tickets mailing list