jim-easterbrook / Photini

An easy to use digital photograph metadata (Exif, IPTC, XMP) editing application.
https://photini.readthedocs.io/
GNU General Public License v3.0
155 stars 24 forks source link

M2 MacBook Segmentation Fault: 11 (get_exif_thumbnail) #211

Closed alexpopov closed 8 months ago

alexpopov commented 9 months ago

Hello!

When opening a TIFF file I scanned myself (scanning b&w film) I get a Segmentation Fault 11 crash. Here's the stack trace:

Fatal Python error: Segmentation fault

Current thread 0x00000001dfc6de00 (most recent call first):
  File "/Users/alp/Development/Photini/src/photini/metadata.py", line 181 in get_exif_thumbnail
  File "/Users/alp/Development/Photini/src/photini/metadata.py", line 470 in read
  File "/Users/alp/Development/Photini/src/photini/metadata.py", line 651 in __init__
  File "/Users/alp/Development/Photini/src/photini/imagelist.py", line 49 in __init__
  File "/Users/alp/Development/Photini/src/photini/imagelist.py", line 653 in open_file
  File "/Users/alp/Development/Photini/src/photini/imagelist.py", line 627 in open_file_list
  File "/Users/alp/Development/Photini/src/photini/pyqt.py", line 191 in wrapper
  File "/Users/alp/Development/Photini/src/photini/imagelist.py", line 603 in open_files
  File "/Users/alp/Development/Photini/src/photini/pyqt.py", line 191 in wrapper
  File "/Users/alp/Development/Photini/src/photini/pyqt.py", line 271 in execute
  File "/Users/alp/Development/Photini/src/photini/editor.py", line 577 in main
  File "/Users/alp/Development/Photini/src/run_photini.py", line 30 in <module>
Segmentation fault: 11

Because of issue #210 I have a made-up version number that I set myself as a work-around, but here's the rest of --version. I'm running master.

The 'enchant' C library was not found and maybe needs to be installed.
See  https://pyenchant.github.io/pyenchant/install.html
for details

Photini 2023.10.01, build sep+
  Python 3.9.6 (default, May  7 2023, 23:32:44)
[Clang 14.0.3 (clang-1403.0.22.14.1)]
  python-exiv2 0.14.1, exiv2 0.27.7
  PySide6 6.5.0, Qt 6.5.0, locale en-CH
  ffmpeg version 6.0 Copyright (c) 2000-2023 the FFmpeg developers
  available styles: macOS, Windows, Fusion
  using style: macos
(photini)

I set a couple breakpoints and it really just seems like the function crashes when get_exif_thumbnail returns—not inside. I wonder if it's something wrong with the PySide6.QtGui.QImage implementation perhaps.

Is there any way I can help debug this?

Note: I tried opening some other image from a normal camera and it worked fine. Here's a link to the TIFF to repro

jim-easterbrook commented 9 months ago

I'm able to reproduce this with your TIFF file and my Linux x86 machine. I suspect the problem will be related to thumbnails or preview images, but I need to investigate further.

PS The M2 has an ARM processor, doesn't it? The "binary wheels" of python-exiv2 (and python-gphoto2) are built with cross-compilation for ARM machines and I've not been able to test them.

jim-easterbrook commented 9 months ago

I've found another TIFF file (from a totally different source) that also causes a segfault, so it's probably not something wrong with your file.

jim-easterbrook commented 9 months ago

I've found that PyQt6 and PySide6 on my Linux machine can read your file's thumbnail / preview without a problem, but PyQt5 and PySide2 segfault. But you're using PySide6.

jim-easterbrook commented 9 months ago

It's Qt version dependent. I'm using OpenSUSE which uses Python 3.6.15, so my usual PyQt6 version is 6.4.2. This can read your tif file's thumbnail without any problem.

I also have Python 3.11.4 installed, which can use PyQt6 version 6.5.2. This segfaults on your tif file.

Downgrading PyQt6 to version 6.4.2 allows it to read your tif file. python3.11 -m pip install PyQt6==6.4.2 PyQt6-Qt6==6.4.2 PyQt6-WebEngine==6.4.0 PyQt6-WebEngine-Qt6==6.4.0

jim-easterbrook commented 9 months ago

A web search on segfaults with QImage finds lots of results, one of which pointed me to this:

The buffer must remain valid throughout the life of the QImage and all copies that have not been modified or otherwise detached from the original buffer. The image does not delete the buffer at destruction.

https://doc.qt.io/qt-6/qimage.html#QImage-3

I'm creating QImages from buffered data so this definitely could be the problem.

jim-easterbrook commented 9 months ago

The solution is to attach the Python buffer object to the Python image object. This keeps a reference to the buffer until the image is destroyed.

jim-easterbrook commented 9 months ago

I've released version 2023.10.0 which should fix this bug.