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

Segfault on Linux at process exit under PySide 6.3.1 #476

Closed
mdickinson opened this issue Jun 22, 2022 · 9 comments
Closed

Segfault on Linux at process exit under PySide 6.3.1 #476

mdickinson opened this issue Jun 22, 2022 · 9 comments

Comments

@mdickinson
Copy link
Member

mdickinson commented Jun 22, 2022

EDIT 2023-03-10: Upstream issue here - https://bugreports.qt.io/browse/PYSIDE-2254


While trying to add support for PySide 6, we're seeing a segfault at process exit time when running the test suite, both on CI and locally.

We've also seen similar segfaults on downstream applications using Envisage.

For me, on a Linux VM, the segfault is reliably reproducible from a given piece of code, but also very fragile: addition or removal of unrelated code lines or unrelated imports can cause the segfault to disappear or reappear. As such, it's very hard to reduce to a minimal failing example. It's almost certainly not Envisage that's the root cause of the problem, and this seems likely to be a bug in PySide 6.

Here's a minimal-ish reproducer script on Ubuntu Linux 20.04.1:

import gc; gc.disable()

import os
import shutil
import tempfile
import unittest

import pkg_resources

from envisage.ui.tasks.api import TasksApplication


class TestTasksApplication(unittest.TestCase):
    def random(self):
        pass

    def test_layout_load(self):
        app = TasksApplication()
        app.on_trait_change(app.exit, "application_initialized")
        app.run()

if __name__ == "__main__":
    unittest.main(exit=False)

Note that the os, shutil, tempfile and pkg_resources imports are completely unused. Nevertheless, I can reproduce the segfault reliably with the above script, but if I remove those unused imports, the script runs without error.

Detailed instructions to reproduce

On Ubuntu 20.04.1 / x86_64, running under VirtualBox on a macOS / Intel host:

  • using the Ubuntu-installed Python 3.8 (python3)
  • using PySide6-6.3.1 from PyPI (which brings in PySide6-Addons, PySide6-Essentials, shiboken6)

The following sequence of instructions reproduces the segfault for me. Replacing the last line with python -m unittest also produces the same crash at the end of the test run.

$ python3 -m venv --clear ~/.venvs/envisage && source ~/.venvs/envisage/bin/activate
$ python -m pip install --upgrade pip setuptools wheel
$ python -m pip install PySide6
$ python -m pip install git+https://github.com/enthought/pyface.git
$ python -m pip install -e .
$ export ETS_TOOLKIT=qt
$ python crasher.py

Here crasher.py is the above script.

Stack trace

Here's the stack trace, obtained by setting ulimit -c unlimited and by killing the Ubuntu crash reporter which will otherwise intercept the core dump (sudo service apport stop):

Core was generated by `python crasher.py'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007fb4f06fd9a2 in Shiboken::BindingManager::retrieveWrapper(void const*) () from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/shiboken6/libshiboken6.abi3.so.6.3
[Current thread is 1 (Thread 0x7fb4f2123740 (LWP 14184))]
(gdb) bt
#0  0x00007fb4f06fd9a2 in Shiboken::BindingManager::retrieveWrapper(void const*) ()
   from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/shiboken6/libshiboken6.abi3.so.6.3
#1  0x00007fb4eff22185 in ?? () from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/PySide6/libpyside6.abi3.so.6.3
#2  0x00007fb4eff2285a in ?? () from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/PySide6/libpyside6.abi3.so.6.3
#3  0x00007fb4efa3455e in QVariant::~QVariant() () from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6
#4  0x00007fb4efa0f40c in QObjectPrivate::~QObjectPrivate() ()
   from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6
#5  0x00007fb4efad4379 in ?? () from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6
#6  0x00007fb4efad4033 in ?? () from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6
#7  0x00007fb4efad4187 in ?? () from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6
#8  0x00007fb4efad43b9 in ?? () from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6
#9  0x00007fb4efa0f2e6 in QObjectPrivate::~QObjectPrivate() ()
   from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6
#10 0x00007fb4efa1d5ac in QObject::~QObject() () from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6
#11 0x00007fb4d9cf9f37 in ?? ()
   from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/PySide6/Qt/plugins/xcbglintegrations/libqxcb-glx-integration.so
#12 0x00007fb4efc5e032 in ?? () from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6
#13 0x00007fb4efc606d3 in ?? () from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6
#14 0x00007fb4efc5e299 in ?? () from /home/mdickinson/.venvs/envisage/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6
#15 0x00007fb4f23358a7 in __run_exit_handlers (status=0, listp=0x7fb4f24db718 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true, 
    run_dtors=run_dtors@entry=true) at exit.c:108
#16 0x00007fb4f2335a60 in __GI_exit (status=<optimised out>) at exit.c:139
#17 0x00007fb4f231308a in __libc_start_main (main=0x4eead0 <main>, argc=2, argv=0x7ffcee6c57e8, init=<optimised out>, fini=<optimised out>, 
    rtld_fini=<optimised out>, stack_end=0x7ffcee6c57d8) at ../csu/libc-start.c:342
#18 0x00000000005fa5ce in _start ()
@mdickinson
Copy link
Member Author

There's a PySide 6.3.2 release; we should test with that.

mdickinson added a commit that referenced this issue Jan 5, 2023
PR updating and fixing our CI for newest Ubuntu and other changes:

- [x] Fix apt-get package list for Ubuntu-22.04
- [x] Move OS package installation into a separate composite action
- [x] Replace uses of `GabrielBB/xvfb-action` action with `xvfb-run`
- [x] Drop matrix entries that require Python 3.6 from
`actions/setup-python`
- [x] Drop PySide2 testing in non-EDM tests (test only on PySide6)
- [x] Bypass copyright year check for now, to avoid cluttering this PR
with copyright fixes; I'll open another issue for this. (#492)

We have three tests that have been causing problematic segfaults: #476.
Those are increasingly interfering with CI runs, even for changes that
have nothing to do with the relevant code, so I'm going to skip those
tests unconditionally in CI + Linux. (That's far from ideal, but I don't
see a better solution.)
mdickinson added a commit that referenced this issue Feb 6, 2023
PR updating and fixing our CI for newest Ubuntu and other changes:

- [x] Fix apt-get package list for Ubuntu-22.04
- [x] Move OS package installation into a separate composite action
- [x] Replace uses of `GabrielBB/xvfb-action` action with `xvfb-run`
- [x] Drop matrix entries that require Python 3.6 from
`actions/setup-python`
- [x] Drop PySide2 testing in non-EDM tests (test only on PySide6)
- [x] Bypass copyright year check for now, to avoid cluttering this PR
with copyright fixes; I'll open another issue for this. (#492)

We have three tests that have been causing problematic segfaults: #476.
Those are increasingly interfering with CI runs, even for changes that
have nothing to do with the relevant code, so I'm going to skip those
tests unconditionally in CI + Linux. (That's far from ideal, but I don't
see a better solution.)

(cherry picked from commit 18da311)
@mdickinson
Copy link
Member Author

This issue should be re-evaluated once the IPython components have been removed.

mdickinson added a commit that referenced this issue Feb 7, 2023
PR updating and fixing our CI for newest Ubuntu and other changes:

- [x] Fix apt-get package list for Ubuntu-22.04
- [x] Move OS package installation into a separate composite action
- [x] Replace uses of `GabrielBB/xvfb-action` action with `xvfb-run`
- [x] Drop matrix entries that require Python 3.6 from
`actions/setup-python`
- [x] Drop PySide2 testing in non-EDM tests (test only on PySide6)
- [x] Bypass copyright year check for now, to avoid cluttering this PR
with copyright fixes; I'll open another issue for this. (#492)

We have three tests that have been causing problematic segfaults: #476.
Those are increasingly interfering with CI runs, even for changes that
have nothing to do with the relevant code, so I'm going to skip those
tests unconditionally in CI + Linux. (That's far from ideal, but I don't
see a better solution.)

(cherry picked from commit 18da311)
@mdickinson mdickinson added this to the Release 7.0 milestone Mar 7, 2023
@mdickinson
Copy link
Member Author

I'm able to reproduce this end-of-process segfault somewhat reliably with:

  • Ubuntu 22.04
  • Python 3.10 (as provided by Ubuntu)
  • PySide6 6.3.2

Here's a single-script crasher:

import unittest

from pyface.gui import GUI
from pyface.tasks.api import TaskWindow
from traits.api import Instance

from envisage.api import Application


class MyTasksApplication(Application):
    window = Instance(TaskWindow)

    def run(self):
        gui = GUI()
        self.start()
        window = TaskWindow()
        window.open()
        self.window = window
        gui.invoke_later(self.exit)
        gui.start_event_loop()
        self.stop()

    def exit(self):
        window = self.window
        self.window = None
        window.destroy()
        window.closed = True



def main():
    app = MyTasksApplication()
    app.run()



if __name__ == "__main__":
    main()

It's still a bit Heisenbuggy: the segfault seems more likely to occur in the presence of the (unused) unittest import, for example.

@mdickinson
Copy link
Member Author

I've now reduced to an example that doesn't involve Envisage at all; opening a Pyface issue shortly.

@mdickinson
Copy link
Member Author

Opened enthought/pyface#1211.

@mdickinson
Copy link
Member Author

The root cause appears to be this: https://bugreports.qt.io/browse/PYSIDE-2254

I'll edit the main issue description so that this is easier to find.

@mdickinson
Copy link
Member Author

mdickinson commented Mar 13, 2023

This is now fixed upstream: it's been both worked around in Pyface and fixed for real in PySide6.

Leaving open here as a reminder to remove the skips on tests as soon as we have either a new release of Pyface or a new release of PySide6.

@mdickinson
Copy link
Member Author

Removing from the 7.0 release milestone. We're dependent on upstream releases (Pyface and/or PySide6), and neither of those should block the Envisage 7.0 release.

@mdickinson mdickinson removed this from the Release 7.0 milestone Mar 14, 2023
@mdickinson
Copy link
Member Author

Leaving open here as a reminder [...]

On second thoughts, for cleanliness, I'll close this issue and open a new one for removing the test skips.

@mdickinson mdickinson closed this as not planned Won't fix, can't repro, duplicate, stale Mar 23, 2023
mdickinson added a commit that referenced this issue Mar 23, 2023
We're currently skipping some GUI-using tests in GitHub Actions runs
because of an end-of-process segfault caused by a PySide6 bug. That bug
is now fixed in the latest release (6.4.3) of PySide6, so this PR tweaks
the skip condition so that the tests will only be skipped with versions
of PySide6 that are older than 6.4.3.

xref: #476
xref: https://bugreports.qt.io/browse/PYSIDE-2254
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant