Nuitka: Access violation/segmentation fault connecting signal (with `QFileSystemWatcher`/`QTimer`)
Good things come in threes. #2086, #2492, and now this. Note this code likely doesn’t do anything useful anymore, it is highly reduced to reproduce the segmentation fault.
crash.py
# nuitka-project: --onefile
# nuitka-project: --static-libpython=no
# nuitka-project: --enable-plugin=pyside6
# nuitka-project: --nofollow-import-to=tkinter
# possibly remove the above since 1.7
# nuitka-project: --noinclude-default-mode=error
# nuitka-project-if: {OS} == "Windows":
# nuitka-project: --output-filename=crash.exe
# nuitka-project-if: {OS} == "Linux":
# nuitka-project: --output-filename=crash.bin
# nuitka-project: --output-dir=dist-nuitka
# nuitka-project: --assume-yes-for-downloads
# With tests:
# nuitka-project: --noinclude-pytest-mode=allow
# nuitka-project: --noinclude-unittest-mode=allow
# nuitka-project: --include-package=_pytest
# nuitka-project: --include-package=pytestqt
# nuitka-project: --include-module=PySide6.QtTest
# nuitka-project: --include-module=test_crash
# nuitka-project: --nofollow-import-to=doctest
# nuitka-project: --include-data-file=test_crash.py=.
from pathlib import Path
import pytest
if __name__ == "__main__":
pytest.main([Path(__file__).parent, "-s"], ["pytestqt.plugin"])
test_crash.py
from contextlib import contextmanager, nullcontext
from window import Window
def test_crash(qtbot, tmp_path):
tmp_file = tmp_path / "tmp_file.raw"
window = Window(tmp_file)
qtbot.addWidget(window)
def write(contents):
with tmp_file.open("wb") as file:
file.write(contents.encode("utf-8"))
@contextmanager
def wait(fixed=0):
signal_wait = qtbot.waitSignal(window.signal, timeout=5000)
with nullcontext() if fixed else signal_wait:
yield
if fixed:
qtbot.wait(fixed)
write("1")
with wait():
window.start()
with wait(fixed=200):
write("12")
with wait():
qtbot.wait(300)
window.py
from PySide6.QtCore import QFileSystemWatcher, QTimer, Signal
from PySide6.QtWidgets import QMainWindow
class Window(QMainWindow):
signal = Signal()
def __init__(self, path):
super().__init__()
self.path = path
self.fsize = self.get_fsize()
self.watcher = QFileSystemWatcher()
self.watcher.fileChanged.connect(self.file_changed)
def get_fsize(self):
try:
return self.path.stat().st_size
except FileNotFoundError:
return 0
def file_changed(self):
if (new_size := self.get_fsize()) != self.fsize:
self.fsize = new_size
QTimer.singleShot(300, self.file_changed)
return
self.start()
def start(self):
self.signal.emit()
self.watcher.addPath(str(self.path))
Setup:
Python=3.11.6
Nuitka==1.9rc5 # 11a3d44ab12c706a54e85c21d5161e2983e1bc01
PySide6-Essentials==6.5.3
pytest==7.4.2
pytest-qt==4.2.0
Run
pytest # works
python -m nuitka crash.py
dist-nuitka/crash.bin # segfaults
Output
====================================================================================== test session starts ======================================================================================platform linux -- Python 3.11.6, pytest-7.4.2, pluggy-1.3.0
PySide6 6.5.3 -- Qt runtime 6.5.3 -- Qt compiled 6.5.3
rootdir: /tmp/onefile_11874_1697322110_687089
collected 1 item
../../../../tmp/onefile_11874_1697322110_687089/test_crash.py Fatal Python error: Segmentation fault
Current thread 0x00007f34dcefab80 (most recent call first):
File "/tmp/onefile_11874_1697322110_687089/pytestqt/wait_signal.py", line 193 in connect
File "/tmp/onefile_11874_1697322110_687089/pytestqt/qtbot.py", line 289 in waitSignal
File "/tmp/onefile_11874_1697322110_687089/test_crash.py", line 18 in wait
File "/tmp/onefile_11874_1697322110_687089/contextlib.py", line 137 in __enter__
File "/tmp/onefile_11874_1697322110_687089/test_crash.py", line 32 in test_crash
File "/tmp/onefile_11874_1697322110_687089/_pytest/python.py", line 194 in pytest_pyfunc_call
File "/tmp/onefile_11874_1697322110_687089/pluggy/_callers.py", line 27 in _multicall
File "/tmp/onefile_11874_1697322110_687089/pluggy/_manager.py", line 106 in _hookexec
File "/tmp/onefile_11874_1697322110_687089/pluggy/_hooks.py", line 479 in __call__
File "/tmp/onefile_11874_1697322110_687089/_pytest/python.py", line 1792 in runtest
File "/tmp/onefile_11874_1697322110_687089/_pytest/runner.py", line 169 in pytest_runtest_call
File "/tmp/onefile_11874_1697322110_687089/pluggy/_callers.py", line 27 in _multicall
File "/tmp/onefile_11874_1697322110_687089/pluggy/_manager.py", line 106 in _hookexec
File "/tmp/onefile_11874_1697322110_687089/pluggy/_hooks.py", line 479 in __call__
File "/tmp/onefile_11874_1697322110_687089/_pytest/runner.py", line 262 in <lambda>
File "/tmp/onefile_11874_1697322110_687089/_pytest/runner.py", line 341 in from_call
File "/tmp/onefile_11874_1697322110_687089/_pytest/runner.py", line 261 in call_runtest_hook
File "/tmp/onefile_11874_1697322110_687089/_pytest/runner.py", line 222 in call_and_report
File "/tmp/onefile_11874_1697322110_687089/_pytest/runner.py", line 133 in runtestprotocol
File "/tmp/onefile_11874_1697322110_687089/_pytest/runner.py", line 114 in pytest_runtest_protocol
File "/tmp/onefile_11874_1697322110_687089/pluggy/_callers.py", line 27 in _multicall
File "/tmp/onefile_11874_1697322110_687089/pluggy/_manager.py", line 106 in _hookexec
File "/tmp/onefile_11874_1697322110_687089/pluggy/_hooks.py", line 479 in __call__
File "/tmp/onefile_11874_1697322110_687089/_pytest/main.py", line 350 in pytest_runtestloop
File "/tmp/onefile_11874_1697322110_687089/pluggy/_callers.py", line 27 in _multicall
File "/tmp/onefile_11874_1697322110_687089/pluggy/_manager.py", line 106 in _hookexec
File "/tmp/onefile_11874_1697322110_687089/pluggy/_hooks.py", line 479 in __call__
File "/tmp/onefile_11874_1697322110_687089/_pytest/main.py", line 325 in _main
File "/tmp/onefile_11874_1697322110_687089/_pytest/main.py", line 271 in wrap_session
File "/tmp/onefile_11874_1697322110_687089/_pytest/main.py", line 318 in pytest_cmdline_main
File "/tmp/onefile_11874_1697322110_687089/pluggy/_callers.py", line 27 in _multicall
File "/tmp/onefile_11874_1697322110_687089/pluggy/_manager.py", line 106 in _hookexec
File "/tmp/onefile_11874_1697322110_687089/pluggy/_hooks.py", line 479 in __call__
File "/tmp/onefile_11874_1697322110_687089/_pytest/config/__init__.py", line 169 in main
About this issue
- Original URL
- State: closed
- Created 9 months ago
- Comments: 15 (7 by maintainers)
It does! Thanks a lot!