Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GEOS aborting with "Assertion failed" on OS X, discussion and work around #553

Open
sgillies opened this issue Jan 1, 2018 · 11 comments

Comments

Projects
None yet
8 participants
@sgillies
Copy link
Member

commented Jan 1, 2018

I've spent a bit of free time looking more deeply into the reports of GEOS aborting in the AbstractSTRtree.cpp module (either in query() or itemsTree()) on OS X when fiona is imported before shapely in a Python script.

Here are the conditions for a program that will unexpectedly abort:

  1. Any version of Python on OS X.
  2. Fiona and Shapely binary wheels for macosx downloaded from PyPI. These wheels include libgeos_c.dylib and libgeos-3.6.2.dylib files.
  3. A script that imports fiona before shapely and which triggers the creation of a GEOS STR R-tree. Calling ops.unary_union with a number of lines or polygons will suffice.

Here's an example program:

import fiona

from shapely.geometry import Point
from shapely.geos import geos_version
from shapely.ops import unary_union

print(geos_version)

SHAPES = [Point(i, i).buffer(1.5) for i in range(20)]
for i, s in enumerate(SHAPES):
    print(i, s.is_valid)
    print(i, s.wkt)
    print(i, s.area, s.length)
    print(i, s.intersects(Point(10, 10).buffer(8.0)))

union = unary_union(SHAPES)
print(union)

I've run the script under lldb with a modified version of GEOS 3.6.2 that prints some debugging output before calling assert().

...
19 7.057234103728362 9.420993470864257
19 False
Assertion failed: (!static_cast<bool>("should never be reached")), function itemsTree, file AbstractSTRtree.cpp, line 379.
dynamic_cast<AbstractNode*>: 0x0dynamic_cast<ItemBoundable*>: 0x0childBoundable: 0x100498510Process 17968 stopped
* thread #1: tid = 0x606ba9, 0x00007fff8d415f06 libsystem_kernel.dylib`__pthread_kill + 10, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00007fff8d415f06 libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill:
->  0x7fff8d415f06 <+10>: jae    0x7fff8d415f10            ; <+20>
    0x7fff8d415f08 <+12>: movq   %rax, %rdi
    0x7fff8d415f0b <+15>: jmp    0x7fff8d4107cd            ; cerror_nocancel
    0x7fff8d415f10 <+20>: retq

I've failed to get access to variables in the frame where assert() is called. I am frankly over my head in trying to debug a dlopen'ed C++ library.

Changing the intersects() call in the script to intersection() leads to another failed assertion and an aborted program the first time there is a non-empty intersection.

...
4 7.057234103728363 9.42099347086426
Assertion failed: (0), function query, file AbstractSTRtree.cpp, line 288.
Process 18002 stopped
* thread #1: tid = 0x6074fe, 0x00007fff8d415f06 libsystem_kernel.dylib`__pthread_kill + 10, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00007fff8d415f06 libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill:
->  0x7fff8d415f06 <+10>: jae    0x7fff8d415f10            ; <+20>
    0x7fff8d415f08 <+12>: movq   %rax, %rdi
    0x7fff8d415f0b <+15>: jmp    0x7fff8d4107cd            ; cerror_nocancel
    0x7fff8d415f10 <+20>: retq

The problem in query() appears to be the same as in itemsTree(): the dynamic casts return null pointers and the library fails by calling assert(0).

https://github.com/OSGeo/geos/blob/master/src/index/strtree/AbstractSTRtree.cpp#L277-L287

If fiona is imported after shapely, the programs (either with intersects() or intersection()) run without problems.

My hypothesis is that there is a race condition in initialization of the libgeos-3.6.2 library that leaves some objects in the AbstractSTRtree.cpp module in a partly or improperly initialized state when we dlopen the GEOS lib after it has already been loaded in the process via import of fiona. Use of GEOS as both a dependent library of fiona modules and as a library we dynamically load during import of shapely is a little weird, I grant, but doesn't necessarily have to trigger crashing bugs. There's no problem on Linux. I see some hints that the difference between ELF and Mach-O might be important.

Workaround 1

Install the GEOS library to one standard location on your macosx system using homebrew, fink, macports, or from source, do the same for GDAL, and then install fiona and shapely like so:

pip install --no-binary shapely,fiona shapely fiona

You can import fiona and shapely in any order if you do this.

Workaround 2

On OS X, if you're using fiona and shapely wheels together, import shapely first. It's annoying to have to do this, I know. Abstracting away the C/C++ details of GEOS and GDAL has been one of my main design principles for fiona and shapely, and I'm falling short.

Solution

I think there's a race condition bug to be fixed in the GEOS library. You can see some indication of that at https://lists.osgeo.org/pipermail/geos-devel/2017-November/008157.html. Because this doesn't affect Linux and PostGIS, it's a very low-flying bug.

Fixing it will require more knowledge and experience with C++ and dynamic library building and loading on Mac OS X than I currently have, and so the fix isn't going to be coming soon unless we can get some help.

I'm somewhat content to at least have a master ticket that I can point users at. It's a start.

/cc @snorfalorpagus @perrygeo

@sgillies

This comment has been minimized.

Copy link
Member Author

commented Jan 3, 2018

@perrygeo

This comment has been minimized.

Copy link
Collaborator

commented Feb 28, 2018

On OS X, if you're using fiona and shapely wheels together, import shapely first.

Noting that import shapely before Fiona is not enough - you need to import any one of the submodules that loads the GEOS dll (import shapely.geometry for instance)

@rudra0713

This comment has been minimized.

Copy link

commented Mar 4, 2018

Hi, I am not using Fiona, only shapely. I was trying to use Shapely's parallel_offset(). Building the program in the terminal is fine but when I tend to check my browser, it crashes with the alert that "Python quit unexpectedly." In my python console, the error says
Assertion failed: (0), function query, file AbstractSTRtree.cpp, line 287.

Process finished with exit code 134 (interrupted by signal 6: SIGABRT)

@dt99jay

This comment has been minimized.

Copy link

commented Apr 7, 2018

I'm getting the same error (Assertion failed: (0), function query, file AbstractSTRtree.cpp, line 287. Abort trap: 6 when calling intersection()) with Rasterio and Shapely (both installed via pip on macOS 10.13.3, Python 3.5.2). The workaround of importing Shapely before Rasterio has fixed it.

ritviksahajpal added a commit to ritviksahajpal/pygeoutil that referenced this issue Jul 5, 2018

ritviksahajpal added a commit to ritviksahajpal/pygeoutil that referenced this issue Jul 5, 2018

ritviksahajpal added a commit to ritviksahajpal/pygeoutil that referenced this issue Jul 5, 2018

@DanRamage

This comment has been minimized.

Copy link

commented Jul 24, 2018

I do not use fiona, but was still experiencing this issue. I first attributed it to spatialite, since I am attempting to get Python 2.7.15 running on OS X and rebuilding libspatialite. Using the --no-binary flag in pip solved my issue it appears.
I didn't suspect shapely since all I am doing is using a Polygon and the wkb_hex value in a Spatialite query that uses an Intersection(). I wasn't using one of the Shapely functions above, strictly Spatialite functions.

I see that a package I use does use Fiona, however it still appears that the --no-binary install for Shapely seems to be sufficient to fix my issue.

@Silmathoron

This comment has been minimized.

Copy link

commented Oct 24, 2018

Still encountering this issue without Fiona (only shapely and GEOS on a mixed Python/C++ library) on OSX and python 3.7.
Using pip install --no-binary shapely, shapely fixed it.

EDIT: shapely version is 1.6.4.post2 and GEOS is 3.7.0

@sgillies

This comment has been minimized.

Copy link
Member Author

commented Oct 24, 2018

Yes, acknowledged. The problem is between GEOS and dlopen (ctypes) and it remains.

@CordThomas

This comment has been minimized.

Copy link

commented Nov 20, 2018

Using the geometry.split method I am getting the same error. I tried installing shapely with the following and still getting the error. Can I not specify a version in this no-binary approach? the reason i have to use --ignore-installed is because I already have a version of Shapely installed that i cannot remove because it's a 'distutils installed project' which I don't quite grok yet.

pip install --ignore-installed --trusted-host pypi.org --trusted-host files.pythonhosted.org --no-binary shapely==1.6.4.post2,fiona shapely==1.6.4.post2 fiona

@sgillies

This comment has been minimized.

Copy link
Member Author

commented Nov 22, 2018

@CordThomas pip install --no-binary shapely,fiona shapely==1.6.4 fiona is the correct usage.

@arigesher

This comment has been minimized.

Copy link

commented Mar 15, 2019

Just to add to this thread, I'm seeing the same behavior in a virtualenv that meets the above descriptions.

Re-installing from source for Fiona and Shapely did not fix the problem.

I did some digging in my virtualenv and found the geos binary installed by rasterio:

.../lib/python3.5/site-packages/rasterio/.dylibs/libgeos-3.6.2.dylib
.../lib/python3.5/site-packages/rasterio/.dylibs/libgeos_c.1.dylib

This appears to have fixed it:

pip uninstall -y rasterio && pip install rasterio==1.0.11 --no-binary rasterio
@sgillies

This comment has been minimized.

Copy link
Member Author

commented Jun 22, 2019

Update: in my experience, shapely 1.7a2 (released yesterday) solves this on OS X. The example program runs with no errors and no crashes. If you'd like to confirm, try pip install -U --pre shapely and let me know how it goes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.