Opened 6 years ago

Last modified 3 years ago

#848 new defect

dynamic_cast yields null pointers in AbstractSTRtree::query and AbstractSTRtree::itemsTree on OS X

Reported by: sgillies Owned by: strk
Priority: major Milestone: 3.6.6
Component: Core Version: 3.6.2
Severity: Unassigned Keywords: index macosx dlopen
Cc:

Description

The Python package named fiona has C extension modules that depend on libgdal and thus libgeos_c. The shapely package uses libgeos_c in a different way: it dynamically loads libgeos_c at run time and accesses its functions using libffi. Often users want to combine shapely and fiona in programs and things get tricky on OS X.

I've been building run-path dependent GEOS libraries that I distribute with fiona and shapely. A Python user on OS X can pip install shapely and pip install fiona and get packages that "just work" without prior installation of GEOS and GDAL. If you install both shapely and fiona from PyPI you get two copies of each of libgeos_c and its C++ lib in your Python site-packages: one under site-packages/shapely and one under site-packages/fiona.

These packages I'm distributing work fine on Linux with no catches. They work fine on OS X with one catch: you must import shapely before you import fiona.

If you import fiona and load its GEOS libraries before you import shapely and dlopen its copy of libgeos_c in a script that indirectly uses the GEOS AbstractSTRtree class, the script can abort due to assertions that should not normally be reached in AbstractSTRtree::query (when GEOSIntersection_r is called) or AbstractSTRtree::itemsTree (when GEOSUnaryUnion_r is called). These assertions are reached because the dynamic casts at https://github.com/OSGeo/geos/blob/master/src/index/strtree/AbstractSTRtree.cpp#L277 and https://github.com/OSGeo/geos/blob/master/src/index/strtree/AbstractSTRtree.cpp#L281 (and the counterparts in itemsTree) yield null pointers.

I've a little more background and notes about workarounds for Python users at https://github.com/Toblerity/Shapely/issues/553. It's good that there are workarounds, but I think there's a problem in GEOS that is worth resolving.

I'm not surprised that this problem is something triggered by Python extension modules. In a compiled program, it's pretty difficult to load multiple copies of a dynamic library, right? I don't know how to do it. With Python extension modules, it's pretty easy to do once you start using install_name_tool on them.

A Python script that will abort when run on OS X using shapely and fiona binary distributions from PyPI is attached.

Attachments (1)

assertion_abort.py (746 bytes ) - added by sgillies 6 years ago.
Python script that imports fiona before shapely and hits failed assertions

Download all attachments as: .zip

Change History (3)

by sgillies, 6 years ago

Attachment: assertion_abort.py added

Python script that imports fiona before shapely and hits failed assertions

comment:1 by robe, 6 years ago

Milestone: 3.6.33.6.4

comment:2 by strk, 3 years ago

Milestone: 3.6.43.6.6

Ticket retargeted after milestone closed

Note: See TracTickets for help on using tickets.