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

Segmentation fault on import when gi is imported #5637

Closed
Fogapod opened this issue Jul 26, 2021 · 21 comments · Fixed by #5651
Closed

Segmentation fault on import when gi is imported #5637

Fogapod opened this issue Jul 26, 2021 · 21 comments · Fixed by #5651

Comments

@Fogapod
Copy link

Fogapod commented Jul 26, 2021

What did you do?

from gi.repository import Gtk
from PIL import ImageOps

What did you expect to happen?

No errors

What actually happened?

[1]    85601 segmentation fault (core dumped)  python azote/main.py

What are your OS, Python and Pillow versions?

  • OS: Arch Linux
  • Python: 3.9.6
  • Pillow: 8.3.1

EDIT: shorter code causing segfault

@radarhere
Copy link
Member

So gi is https://pypi.org/project/PyGObject/

If I take our arch Docker image, and add this in, there is no problem.

@radarhere
Copy link
Member

At the start of ImageOps, we have

import functools
import operator
import re

Are you able to test this locally, and see if it is not ImageOps causing the problem directly, but actually functools, operator or re? Maybe this crash can be replicated without importing Pillow at all. Does this code load for you?

from gi.repository import Gtk
import functools
import operator
import re

@Fogapod
Copy link
Author

Fogapod commented Jul 26, 2021

from gi.repository import Gtk
import functools
import operator
import re

This code works for me. (assuming there is also from PIL import Image before that)
I only get segfault behaviour when I import Image, then gi, then ImageOps.
Changing order or removing any step removes segfault.

@Fogapod
Copy link
Author

Fogapod commented Jul 26, 2021

Actually, this is wrong.

from gi.repository import Gtk
from PIL import ImageOps

These 2 lines cause segfault. No Image import needed.

@Fogapod

This comment has been minimized.

@Fogapod
Copy link
Author

Fogapod commented Jul 26, 2021

On 8.3.x branch which I have: https://github.com/python-pillow/Pillow/tree/8.3.x
There is ImageDraw import which imports ImageFont which imports _imagingft.

from gi.repository import Gtk
from PIL import _imagingft

This c file causes segfault.

@wiredfool
Copy link
Member

I bet you're getting a shared library conflict with freetype or one of the other things in the font stack.

@wiredfool
Copy link
Member

To unpack a bit -- your gtk is going to have some associated versions of the freetype/raqm libs, and we're not necessarily going to ship the same ones in our binary wheels. Since you're hosting this in the same process, you need to have one version of the libraries, and that's going to be whatever is on your system that GTK is linking to. (assuming that your gtk is using system packages, because the wheels would be immense otherwise).

So try building Pillow from source --activate your virtualenv or whatever, clone the source and check out 8.3.1. Then make install in the pillow directory should give you something that works.

@Fogapod
Copy link
Author

Fogapod commented Jul 26, 2021

Swapping imports does not cause segmentation fault though. Does this mean gtk has some workaround/fallback for this conflict which Pillow does not?

@radarhere
Copy link
Member

On 8.3.x branch which I have: https://github.com/python-pillow/Pillow/tree/8.3.x
There is ImageDraw import which imports ImageFont which imports _imagingft.

That import was removed by #5615. So if it helps you at all, that will be removed from ImageOps in the next release of Pillow, on October 15th.

@radarhere
Copy link
Member

So try building Pillow from source --activate your virtualenv or whatever, clone the source and check out 8.3.1. Then make install in the pillow directory should give you something that works.

While my last attempt to replicate was through make - installing through pip instead does trigger the segfault.

@radarhere
Copy link
Member

How did you actually install Pillow?

@Fogapod
Copy link
Author

Fogapod commented Jul 29, 2021

Using pip, from pypi

@radarhere
Copy link
Member

Thanks. If you're interested, a simpler alternative to installing through make should be to use pip without binary wheels - pip install Pillow --no-binary :all:

@explode
Copy link

explode commented Aug 1, 2021

I saw a similar conflict with matplotlib:

import matplotlib.pyplot as plt
from PIL import ImageDraw

will cause a segmentation fault, or swap the lines (i.e. import PIL first) and it works OK.
(OS: Ubuntu 20.04, Python: 3.8.10, pip: 21.2.2, Matplotlib: 3.4.2, Pillow: 8.3.1)

@wyatt8740
Copy link

wyatt8740 commented Aug 2, 2021

I bet you're getting a shared library conflict with freetype or one of the other things in the font stack.

Yeah, I have this happening on my Debian Sid machine right now (Pillow 8.3.1, installed via pip3). It seems to be segfaulting in fribidi_load() (when running mcomix3).

Program received signal SIGSEGV, Segmentation fault.
r0x00007ffff27c196a in load_fribidi ()
   from /home/wyatt/.local/lib/python3.9/site-packages/PIL/_imagingft.cpython-39-x86_64-linux-gnu.so

Seems like swapping import ordering is working here, too, but I don't think that's really a good solution since there's still some incorrect behavior happening somewhere that's not fundamentally fixed. Also, it's not very "pythonic" to segfault if import ordering is switched up :)

Additionally, the old version of Pillow I had (8.0.1) does not cause this segfault regardless of import order. I think that is from before Fribidi was introduced to the stack, though.

@nulano
Copy link
Contributor

nulano commented Aug 2, 2021

I managed to reproduce this on the wheel builder and made a potential fix that fixes the segfault.

@Fogapod @wyatt8740 Could you please test with the wheel from https://github.com/nulano/pillow-wheels/actions/runs/1091871497 (download the wheels artifact, unzip, and install the wheel with python -m pip install Pillow-8.4.0.dev0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl, using Python 3.9 x64)?

@Fogapod
Copy link
Author

Fogapod commented Aug 3, 2021

I managed to reproduce this on the wheel builder and made a potential fix that fixes the segfault.

@Fogapod @wyatt8740 Could you please test with the wheel from https://github.com/nulano/pillow-wheels/actions/runs/1091871497 (download the wheels artifact, unzip, and install the wheel with python -m pip install Pillow-8.4.0.dev0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl, using Python 3.9 x64)?

It worked:

$ python -c "from gi.repository import Gtk;from PIL import _imagingft"
<string>:1: PyGIWarning: Gtk was imported without specifying a version first. Use gi.require_version('Gtk', '3.0') before import to ensure that the right version gets loaded.

Older Pillow:

$ python -c "from gi.repository import Gtk;from PIL import _imagingft"
<string>:1: PyGIWarning: Gtk was imported without specifying a version first. Use gi.require_version('Gtk', '3.0') before import to ensure that the right version gets loaded.
[1]    708711 segmentation fault (core dumped)  python -c "from gi.repository import Gtk;from PIL import _imagingft"

@wyatt8740
Copy link

@nulano yes, this wheel fixes my crash. Thank you.

@cydanil
Copy link

cydanil commented Aug 16, 2021

Thanks, I also encountered a similar issue with pillow==8.3.1 and PyGObject==3.40.1.

I could reduce it down to the code below:

import gi
from gi.repository import Gtk, Gdk, GdkPixbuf
from PIL import ImageDraw

which would segfault.

Modifying this excerpt by importing pillow first resolved the issue:

import gi
from PIL import ImageDraw
from gi.repository import Gtk, Gdk, GdkPixbuf

With pillow==8.3.0, the order does not matter and the code runs fine.
The wheel linked above also resolves the issue in my case!

cydanil added a commit to cydanil/gourmand that referenced this issue Aug 16, 2021
Version 8.3.1 may segfault when gi.Gdk is imported before PIL.
This will be fixed in Pillow==8.4.0.

See:
python-pillow/Pillow#5637 (comment)
cydanil added a commit to GourmandRecipeManager/gourmand that referenced this issue Aug 17, 2021
Version 8.3.1 may segfault when gi.Gdk is imported before PIL.
This will be fixed in Pillow==8.4.0.

See:
python-pillow/Pillow#5637 (comment)
@radarhere
Copy link
Member

Pillow 8.3.2 has just been released with the fix for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants