View Ticket
Not logged in
2020-08-26
07:15 Closed ticket [9183e58794]: resolving GEOS memory leaks plus 4 other changes artifact: a7af5b532e user: sandro
2016-07-06
06:44 Ticket [9183e58794]: 3 changes artifact: 74b04720be user: strk
2016-07-05
12:51 Ticket [9183e58794]: 3 changes artifact: e51eaa62fb user: mj10777
2016-07-04
13:06 Ticket [9183e58794]: 5 changes artifact: 48d2b3599d user: mj10777
2016-06-25
06:03 New ticket [9183e58794]. artifact: ebd7d96c30 user: mj10777

Ticket Hash: 9183e58794adbb69a86b0389ad54c31ab6b3bad2
Title: resolving GEOS memory leaks
Status: Closed Type: Documentation
Severity: Important Priority: Low
Subsystem: Resolution: Overcome_By_Events
Last Modified: 2020-08-26 07:15:24
Version Found In: 4.4.0-RC1
User Comments:
mj10777 added on 2016-06-25 06:03:48:

GEOS specific (version 3.5.0)
When using Valgrind, I am always relieved to see that there are no reports before the 2 GEOS specific Memory leaks which always occur:

==6544== 16 bytes in 1 blocks are still reachable in loss record 1 of 8
==6544==    at 0x4C2B100: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6544==    by 0x9279260: geos::geom::GeometryFactory::GeometryFactory() (GeometryFactory.cpp:86)
==6544==    by 0x927B764: geos::geom::GeometryFactory::getDefaultInstance() (GeometryFactory.cpp:728)
==6544==    by 0x740CA6B: GEOS_init_r (geos_ts_c.cpp:165)
==6544==    by 0x51CD47A: spatialite_alloc_reentrant (alloc_cache.c:427)
==6544==    by 0x51CD47A: spatialite_alloc_connection (alloc_cache.c:455)
==6544==    by 0x401867: main (rl2sniff_album.c:2308)
==6544== 
==6544== 32 bytes in 1 blocks are still reachable in loss record 2 of 8
==6544==    at 0x4C2B100: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6544==    by 0x927B759: geos::geom::GeometryFactory::getDefaultInstance() (GeometryFactory.cpp:728)
==6544==    by 0x740CA6B: GEOS_init_r (geos_ts_c.cpp:165)
==6544==    by 0x51CD47A: spatialite_alloc_reentrant (alloc_cache.c:427)
==6544==    by 0x51CD47A: spatialite_alloc_connection (alloc_cache.c:455)
==6544==    by 0x401867: main (rl2sniff_album.c:2308)
The GEOS structure, created in GEOS_init_r and deleted in finishGEOS_r, is called GEOSContextHandle_HS and contains 3 pointers:
const GeometryFactory *geomFactory;
void *noticeData;
void *errorData;
This strucure is deleted in
    geos-3.5.0/capi/geos_ts_c.cpp:finishGEOS_r(GEOSContextHandle_t extHandle)
without any checking if these pointer need to be freed.

geomFactory is the pointer causing the memory leaks

The following code, added in the above function, before the 'delete extHandle;', resolves the memory leaks:
    GEOSContextHandleInternal_t *handle = 0;
    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
    if (handle)
    {
     if (handle->geomFactory)
     {
      const GeometryFactory *gf = handle->geomFactory;
      delete gf;
      handle->geomFactory=NULL;      
     }
     // a free(handle->noticeData) and/or free(handle->errorData) causes errors
    }
    // Fix up freeing handle w.r.t. malloc above
    delete extHandle;
Attemts to free the other 2 pointers (when != NULL) can cause the following:
==24737== Invalid free() / delete / delete[] / realloc()
==24737==    at 0x4C2BE10: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24737==    by 0x740CCED: finishGEOS_r (geos_ts_c.cpp:404)
==24737==    by 0x51CCD8D: free_internal_cache (alloc_cache.c:630)
==24737==    by 0x4F1F119: spatialite_cleanup_ex (spatialite.c:39217)
==24737==    by 0x4019D7: main (rl2sniff_album.c:2380)
==24737==  Address 0xf8ab4e0 is 0 bytes inside a block of size 1,064 free'd
==24737==    at 0x4C2BE10: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24737==    by 0x740CCD1: finishGEOS_r (geos_ts_c.cpp:399)
==24737==    by 0x51CCD8D: free_internal_cache (alloc_cache.c:630)
==24737==    by 0x4F1F119: spatialite_cleanup_ex (spatialite.c:39217)
==24737==    by 0x4019D7: main (rl2sniff_album.c:2380)
==24737== 

plus a few dozen:
Invalid read/write of size 8
I assume, because they have already been freed, without the pointer being set to NULL;
Being a GEOS problem, I suppose this should be reported the GEOS project (Sandro Santilli?).
I assume, however, that you also receive these errors.
So as a second check that the above changes work correctly would be useful, before reporting.
Then the GEOS project could concentrate on whether there may be any other side effects to such a change.

Having no memory leaks in any of the spatial-libraries being used would then be achived.

The only other leaks I can see come from libpixman
==24737== 2,064 bytes in 1 blocks are still reachable in loss record 6 of 6
==24737==    at 0x4C2ABA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24737==    by 0x9AEF69A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.32.4)
==24737==    by 0x9AF230F: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.32.4)
==24737==    by 0x9AA2398: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.32.4)
==24737==    by 0x4010139: call_init.part.0 (dl-init.c:78)
==24737==    by 0x4010222: call_init (dl-init.c:36)
==24737==    by 0x4010222: _dl_init (dl-init.c:126)
==24737==    by 0x4001249: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==24737==    by 0x3: ???
==24737==    by 0xFFEFFFD86: ???
==24737==    by 0xFFEFFFD95: ???
==24737==    by 0xFFEFFFD9B: ???
==24737==    by 0xFFEFFFDA0: ???
==24737== 
==24737== LEAK SUMMARY:
==24737==    definitely lost: 0 bytes in 0 blocks
==24737==    indirectly lost: 0 bytes in 0 blocks
==24737==      possibly lost: 0 bytes in 0 blocks
==24737==    still reachable: 12,384 bytes in 6 blocks
==24737==         suppressed: 0 bytes in 0 blocks
Which I assume only occurs when using RasterLite2.


mj10777 added on 2016-07-04 13:06:38:

This solution causes QGIS (using gdal-ogr) to crash

OGRDestroyPreparedGeometry(_OGRPreparedGeometry*) (ogrgeometry.cpp:4742)
So this must be dealt with differently.
But at the moment: I have no idea how.


mj10777 added on 2016-07-05 12:51:50:

Opened GEOS ticket:
2 GEOS specific Memory leaks when using spatialite


strk added on 2016-07-06 06:44:25:
Older existing ticket is: https://trac.osgeo.org/geos/ticket/587

sandro added on 2020-08-26 07:15:24:
too old to be still considered