Bug with Pyside 6
-
Hello everybody out there!
I encountered a bug with Pyside 6.10.1. Here are information about it:
Summary
Segfault occurs during automatic destruction of
QApplicationby PySide6, whenQWindowContainer(created withQWidget::createWindowContainer()) tries to access aQWindow(Qt3DWindow) that has already been destroyed or is invalid.Environment
- OS: Linux (Ubuntu/Debian) - kernel 6.17.0-7-generic
- Display server: Wayland, on Gnome 49 (gdm-wayland)
- Python: 3.14.0
- PySide6: 6.10.1
- Qt: 6.x (via PySide6)
- Architecture: x86_64
Problem Description
When closing a PySide6 application that uses
QWidget::createWindowContainer()to embed aQt3DWindowinto a widget hierarchy, a segfault occurs inQWindowContainer::toplevelAboutToBeDestroyed().The segfault occurs after the application has completed its work (simulation complete, profiling report displayed), during the automatic destruction of
QApplicationby PySide6.Complete GDB Backtrace
Thread 1 (Thread 0x7ffff7e1e140 (LWP 785642) "python3"): #0 0x00007ffff544ee94 in QWindow::parent(QWindow::AncestorMode) const () from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/Qt/lib/libQt6Gui.so.6 #1 0x00007ffff600d7fb in QWindowContainer::toplevelAboutToBeDestroyed(QWidget*) from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/Qt/lib/libQt6Widgets.so.6 #2 0x00007ffff600d641 in ??? from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/Qt/lib/libQt6Widgets.so.6 #3 0x00007ffff5fd5639 in QWidgetPrivate::deleteTLSysExtra() from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/Qt/lib/libQt6Widgets.so.6 #4 0x00007ffff5fe93f8 in QWidget::destroy(bool, bool) from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/Qt/lib/libQt6Widgets.so.6 #5 0x00007ffff5f92832 in QApplication::~QApplication() from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/Qt/lib/libQt6Widgets.so.6 #6 0x00007ffff69e0f84 in ??? from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/QtWidgets.abi3.so #7 0x00007ffff715c252 in PySide::destroyQCoreApplication() from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/libpyside6.abi3.so.6.10 #8 0x00007ffff715fa09 in PySide::runCleanupFunctions() from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/libpyside6.abi3.so.6.10 #9 0x00007ffff14cbade in ??? from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/QtCore.abi3.so #10 0x00000000006bf2ab in ??? #11 0x00000000006a08f3 in ??? #12 0x00000000006b39f0 in Py_RunMain () #13 0x0000000000667ab4 in Py_BytesMain () #14 0x00007ffff7a2a575 in __libc_start_call_main (main=main@entry=0x667a70, argc=argc@entry=9, argv=argv@entry=0x7fffffffca08) at ../sysdeps/nptl/libc_start_call_main.h:58 #15 0x00007ffff7a2a628 in __libc_start_main_impl (main=0x667a70, argc=9, argv=0x7fffffffca08, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffc9f8) at ../csu/libc-start.c:360 #16 0x0000000000666e85 in _start ()Event Sequence
- Application terminates normally (simulation complete, report displayed)
- PySide6 automatically destroys
QApplicationviaPySide::destroyQCoreApplication() - Qt destroys all remaining widgets via
QWidget::destroy() QWindowContainer::toplevelAboutToBeDestroyed()is called- The container tries to access the
QWindow(Display) viaQWindow::parent() - SEGFAULT: The
QWindowis already destroyed or invalid
Expected Behavior
The application should terminate cleanly without segfault, even if
QWindowContainerstill exists whenQApplicationis destroyed.Observed Behavior
Segfault during automatic destruction of
QApplicationby PySide6.Suspected Root Cause
The problem appears to stem from automatic destruction of
QApplicationby PySide6, which occurs before all widgets are completely destroyed. In C++, the same code works because:QApplicationis destroyed explicitly at the end ofmain(), after all widgets are destroyed- Destruction in C++ is synchronous (
delete container;destroys immediately) - In Python, destruction is asynchronous (garbage collector + event loop), and even with many calls to
processEvents(), the container may still exist whenQApplicationis destroyed
Additionally,
QWindowContainer::toplevelAboutToBeDestroyed()callsQWindow::parent()without checking if theQWindowis still valid, which causes the segfault.Minimal Code to Reproduce
A minimal example is available in
test_segfault_minimal.py. Here is the code:#!/usr/bin/env python3 import sys from PySide6.QtWidgets import QApplication, QMainWindow, QWidget from PySide6.Qt3DExtras import Qt3DWindow from PySide6.Qt3DCore import Qt3DCore class Simple3DWindow(Qt3DWindow): def __init__(self, parent=None): super().__init__(parent) self._root_entity = Qt3DCore.QEntity() self.setRootEntity(self._root_entity) self.camera().lens().setPerspectiveProjection(45.0, 16.0/9.0, 0.1, 1000.0) self.camera().setPosition(Qt3DCore.QVector3D(0, 0, 20.0)) self.camera().setViewCenter(Qt3DCore.QVector3D(0, 0, 0)) def main(): app = QApplication(sys.argv) main_window = QMainWindow() main_window.setWindowTitle("Test QWindowContainer Segfault") main_window.resize(800, 600) display = Simple3DWindow() container = QWidget.createWindowContainer(display) # ← Problem here main_window.setCentralWidget(container) main_window.show() result = app.exec() # Explicit cleanup (even with this cleanup, segfault occurs) main_window.setCentralWidget(None) container.hide() display.setParent(None) del display import gc gc.collect() # QApplication will be automatically destroyed by PySide6 → SEGFAULT return result if __name__ == "__main__": sys.exit(main())How to Reproduce
- Save the code above in a file
test_segfault_minimal.py - Run:
python3 test_segfault_minimal.py - Close the window (or wait for program to finish)
- Result: Segfault during
QApplicationdestruction
Resolution Attempts
All of the following attempts have failed:
- ❌ Destroy the
QWindow(Display) before the container - ❌ Destroy the container before the
QWindow - ❌ Detach the
QWindowwithsetParent(None) - ❌ Multiple calls to
processEvents()(up to 30 iterations) - ❌ Forced garbage collection with
gc.collect() - ❌ Using
deleteLater()and waiting withQApplication.processEvents()
Comparison with C++
The same code in C++ works without issues:
int main(int argc, char* argv[]) { QApplication app(argc, argv); QMainWindow mainWindow; Qt3DExtras::Qt3DWindow* display = new Qt3DExtras::Qt3DWindow(); QWidget* container = QWidget::createWindowContainer(display); mainWindow.setCentralWidget(container); mainWindow.show(); int result = app.exec(); // Explicit cleanup - works in C++ mainWindow.setCentralWidget(nullptr); delete display; // SYNCHRONOUS delete container; // SYNCHRONOUS delete &mainWindow; // SYNCHRONOUS // QApplication is destroyed at the end of main() // At this point, ALL widgets are already destroyed return result; }Why it works in C++:
- Destruction is synchronous (
deletedestroys immediately) QApplicationis destroyed after all widgets are destroyed- Destruction order is guaranteed
Why it doesn't work in Python:
- Destruction is asynchronous (garbage collector + event loop)
- PySide6 destroys
QApplicationautomatically during module finalization - Destruction order is not guaranteed
Impact
- Severity: Medium (application works correctly until the end, but terminates with segfault)
- Frequency: 100% (reproducible on every run)
- Workaround: No reliable workaround found. The only solution is to avoid
QWidget::createWindowContainer()or accept the segfault.
Additional Information
Libraries Involved
libQt6Gui.so.6:QWindow::parent()libQt6Widgets.so.6:QWindowContainer::toplevelAboutToBeDestroyed()PySide6/QtWidgets.abi3.so: Destruction ofQApplicationfrom Pythonlibpyside6.abi3.so.6.10: PySide6 cleanup
Similar Issues
Similar issues have been reported with PySide6:
- Segfaults with
QRunnable(signal management) - Segfaults with
QWebEngineView(event filters) - Segfaults with
pyside6-designer(Wayland/X11)
Suggestions
- Check
QWindowvalidity inQWindowContainer::toplevelAboutToBeDestroyed()before callingQWindow::parent() - Guarantee destruction order: Ensure all widgets are completely destroyed before
QApplicationis destroyed by PySide6 - Document behavior: If this behavior is expected, document it clearly in PySide6 documentation
Log Files
- Complete GDB backtrace: Available above
- System logs: No system logs generated (silent segfault)
Project Information
This bug was discovered while working on a benchmarking project comparing C++ and Python implementations of a physics simulation:
- Main project: Python with framework benchmarking
- Python repository: pure-python
- C++ repository: pure-cpp
The C++ version of the same code works correctly, demonstrating that this is a PySide6-specific issue rather than a Qt design problem.
Note for PySide6 Developers
This bug appears to be related to PySide6's management of Qt object lifecycles, particularly during automatic destruction of
QApplication. The fact that the same code works in C++ suggests that the problem is specific to PySide6 and how it manages Qt object destruction in Python.A possible solution would be to:
- Explicitly destroy all widgets before destroying
QApplicationinPySide::destroyQCoreApplication() - Or add a check in
QWindowContainer::toplevelAboutToBeDestroyed()to ensure theQWindowis still valid before accessing it
Best regards.
-
Welcome to the forum.
Thanks for the unusually detailed description of the problem you are experiencing.
This is a user forum and is not necessarily monitored by any Qt developer or support staff. It is possible that someone here with the necessary PySide tooling can help find/see the issue. If you want to lodge a formal bug then this is the place to go.
-
Hi and welcome to the forum,
thanks for the comprehensive report.
What you experience is a double delete, caused by deletingdisplay(i.e. the window insidecontainer) after the event loop has been finished. On the one hand, a window container without anything inside isn't of much use. On the other hand, why not letQApplicationdeal with the cleanup? It knows all widgets that are around (->QApplication::allWidgets()) and will destroy them properly. And why deleting stuff afterQApplication::exec()?Furthermore, the Python and C++ code isn't identical.
- In C++,
containeranddisplayare deleted, which is correct. Also&mainWindowis deleted, which is a no-go (never delete objects allocated on the stack). - In Python, only
displayis deleted;containeris just hidden.
=> That's why the code behaves differently.
To sum it up:
- None of the destructions are necessary.
- Let
QApplicationdeal with all destructions. - If you believe otherwise, please explain and put them before
QApplication::exec()
- In C++,
-
Hello everybody out there!
I encountered a bug with Pyside 6.10.1. Here are information about it:
Summary
Segfault occurs during automatic destruction of
QApplicationby PySide6, whenQWindowContainer(created withQWidget::createWindowContainer()) tries to access aQWindow(Qt3DWindow) that has already been destroyed or is invalid.Environment
- OS: Linux (Ubuntu/Debian) - kernel 6.17.0-7-generic
- Display server: Wayland, on Gnome 49 (gdm-wayland)
- Python: 3.14.0
- PySide6: 6.10.1
- Qt: 6.x (via PySide6)
- Architecture: x86_64
Problem Description
When closing a PySide6 application that uses
QWidget::createWindowContainer()to embed aQt3DWindowinto a widget hierarchy, a segfault occurs inQWindowContainer::toplevelAboutToBeDestroyed().The segfault occurs after the application has completed its work (simulation complete, profiling report displayed), during the automatic destruction of
QApplicationby PySide6.Complete GDB Backtrace
Thread 1 (Thread 0x7ffff7e1e140 (LWP 785642) "python3"): #0 0x00007ffff544ee94 in QWindow::parent(QWindow::AncestorMode) const () from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/Qt/lib/libQt6Gui.so.6 #1 0x00007ffff600d7fb in QWindowContainer::toplevelAboutToBeDestroyed(QWidget*) from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/Qt/lib/libQt6Widgets.so.6 #2 0x00007ffff600d641 in ??? from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/Qt/lib/libQt6Widgets.so.6 #3 0x00007ffff5fd5639 in QWidgetPrivate::deleteTLSysExtra() from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/Qt/lib/libQt6Widgets.so.6 #4 0x00007ffff5fe93f8 in QWidget::destroy(bool, bool) from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/Qt/lib/libQt6Widgets.so.6 #5 0x00007ffff5f92832 in QApplication::~QApplication() from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/Qt/lib/libQt6Widgets.so.6 #6 0x00007ffff69e0f84 in ??? from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/QtWidgets.abi3.so #7 0x00007ffff715c252 in PySide::destroyQCoreApplication() from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/libpyside6.abi3.so.6.10 #8 0x00007ffff715fa09 in PySide::runCleanupFunctions() from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/libpyside6.abi3.so.6.10 #9 0x00007ffff14cbade in ??? from /home/yoann/Programmes/Python/pure-python/venv/lib/python3.14/site-packages/PySide6/QtCore.abi3.so #10 0x00000000006bf2ab in ??? #11 0x00000000006a08f3 in ??? #12 0x00000000006b39f0 in Py_RunMain () #13 0x0000000000667ab4 in Py_BytesMain () #14 0x00007ffff7a2a575 in __libc_start_call_main (main=main@entry=0x667a70, argc=argc@entry=9, argv=argv@entry=0x7fffffffca08) at ../sysdeps/nptl/libc_start_call_main.h:58 #15 0x00007ffff7a2a628 in __libc_start_main_impl (main=0x667a70, argc=9, argv=0x7fffffffca08, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffc9f8) at ../csu/libc-start.c:360 #16 0x0000000000666e85 in _start ()Event Sequence
- Application terminates normally (simulation complete, report displayed)
- PySide6 automatically destroys
QApplicationviaPySide::destroyQCoreApplication() - Qt destroys all remaining widgets via
QWidget::destroy() QWindowContainer::toplevelAboutToBeDestroyed()is called- The container tries to access the
QWindow(Display) viaQWindow::parent() - SEGFAULT: The
QWindowis already destroyed or invalid
Expected Behavior
The application should terminate cleanly without segfault, even if
QWindowContainerstill exists whenQApplicationis destroyed.Observed Behavior
Segfault during automatic destruction of
QApplicationby PySide6.Suspected Root Cause
The problem appears to stem from automatic destruction of
QApplicationby PySide6, which occurs before all widgets are completely destroyed. In C++, the same code works because:QApplicationis destroyed explicitly at the end ofmain(), after all widgets are destroyed- Destruction in C++ is synchronous (
delete container;destroys immediately) - In Python, destruction is asynchronous (garbage collector + event loop), and even with many calls to
processEvents(), the container may still exist whenQApplicationis destroyed
Additionally,
QWindowContainer::toplevelAboutToBeDestroyed()callsQWindow::parent()without checking if theQWindowis still valid, which causes the segfault.Minimal Code to Reproduce
A minimal example is available in
test_segfault_minimal.py. Here is the code:#!/usr/bin/env python3 import sys from PySide6.QtWidgets import QApplication, QMainWindow, QWidget from PySide6.Qt3DExtras import Qt3DWindow from PySide6.Qt3DCore import Qt3DCore class Simple3DWindow(Qt3DWindow): def __init__(self, parent=None): super().__init__(parent) self._root_entity = Qt3DCore.QEntity() self.setRootEntity(self._root_entity) self.camera().lens().setPerspectiveProjection(45.0, 16.0/9.0, 0.1, 1000.0) self.camera().setPosition(Qt3DCore.QVector3D(0, 0, 20.0)) self.camera().setViewCenter(Qt3DCore.QVector3D(0, 0, 0)) def main(): app = QApplication(sys.argv) main_window = QMainWindow() main_window.setWindowTitle("Test QWindowContainer Segfault") main_window.resize(800, 600) display = Simple3DWindow() container = QWidget.createWindowContainer(display) # ← Problem here main_window.setCentralWidget(container) main_window.show() result = app.exec() # Explicit cleanup (even with this cleanup, segfault occurs) main_window.setCentralWidget(None) container.hide() display.setParent(None) del display import gc gc.collect() # QApplication will be automatically destroyed by PySide6 → SEGFAULT return result if __name__ == "__main__": sys.exit(main())How to Reproduce
- Save the code above in a file
test_segfault_minimal.py - Run:
python3 test_segfault_minimal.py - Close the window (or wait for program to finish)
- Result: Segfault during
QApplicationdestruction
Resolution Attempts
All of the following attempts have failed:
- ❌ Destroy the
QWindow(Display) before the container - ❌ Destroy the container before the
QWindow - ❌ Detach the
QWindowwithsetParent(None) - ❌ Multiple calls to
processEvents()(up to 30 iterations) - ❌ Forced garbage collection with
gc.collect() - ❌ Using
deleteLater()and waiting withQApplication.processEvents()
Comparison with C++
The same code in C++ works without issues:
int main(int argc, char* argv[]) { QApplication app(argc, argv); QMainWindow mainWindow; Qt3DExtras::Qt3DWindow* display = new Qt3DExtras::Qt3DWindow(); QWidget* container = QWidget::createWindowContainer(display); mainWindow.setCentralWidget(container); mainWindow.show(); int result = app.exec(); // Explicit cleanup - works in C++ mainWindow.setCentralWidget(nullptr); delete display; // SYNCHRONOUS delete container; // SYNCHRONOUS delete &mainWindow; // SYNCHRONOUS // QApplication is destroyed at the end of main() // At this point, ALL widgets are already destroyed return result; }Why it works in C++:
- Destruction is synchronous (
deletedestroys immediately) QApplicationis destroyed after all widgets are destroyed- Destruction order is guaranteed
Why it doesn't work in Python:
- Destruction is asynchronous (garbage collector + event loop)
- PySide6 destroys
QApplicationautomatically during module finalization - Destruction order is not guaranteed
Impact
- Severity: Medium (application works correctly until the end, but terminates with segfault)
- Frequency: 100% (reproducible on every run)
- Workaround: No reliable workaround found. The only solution is to avoid
QWidget::createWindowContainer()or accept the segfault.
Additional Information
Libraries Involved
libQt6Gui.so.6:QWindow::parent()libQt6Widgets.so.6:QWindowContainer::toplevelAboutToBeDestroyed()PySide6/QtWidgets.abi3.so: Destruction ofQApplicationfrom Pythonlibpyside6.abi3.so.6.10: PySide6 cleanup
Similar Issues
Similar issues have been reported with PySide6:
- Segfaults with
QRunnable(signal management) - Segfaults with
QWebEngineView(event filters) - Segfaults with
pyside6-designer(Wayland/X11)
Suggestions
- Check
QWindowvalidity inQWindowContainer::toplevelAboutToBeDestroyed()before callingQWindow::parent() - Guarantee destruction order: Ensure all widgets are completely destroyed before
QApplicationis destroyed by PySide6 - Document behavior: If this behavior is expected, document it clearly in PySide6 documentation
Log Files
- Complete GDB backtrace: Available above
- System logs: No system logs generated (silent segfault)
Project Information
This bug was discovered while working on a benchmarking project comparing C++ and Python implementations of a physics simulation:
- Main project: Python with framework benchmarking
- Python repository: pure-python
- C++ repository: pure-cpp
The C++ version of the same code works correctly, demonstrating that this is a PySide6-specific issue rather than a Qt design problem.
Note for PySide6 Developers
This bug appears to be related to PySide6's management of Qt object lifecycles, particularly during automatic destruction of
QApplication. The fact that the same code works in C++ suggests that the problem is specific to PySide6 and how it manages Qt object destruction in Python.A possible solution would be to:
- Explicitly destroy all widgets before destroying
QApplicationinPySide::destroyQCoreApplication() - Or add a check in
QWindowContainer::toplevelAboutToBeDestroyed()to ensure theQWindowis still valid before accessing it
Best regards.
-
Welcome to the forum.
Thanks for the unusually detailed description of the problem you are experiencing.
This is a user forum and is not necessarily monitored by any Qt developer or support staff. It is possible that someone here with the necessary PySide tooling can help find/see the issue. If you want to lodge a formal bug then this is the place to go.
Hello everybody out there!
Thank you for your quick answer and my apologies for my late response.
@ChrisW67 said in Bug with Pyside 6:
If you want to lodge a formal bug then this is the place to go.
Well, I have tried and create an issue, but it turned out I was not allowed to create a ticket. However, answers to this thread have proved I shouldn’t create an issue, see below. Thank you for the advice.
@Axel-Spoerl said in Bug with Pyside 6:
Hi and welcome to the forum,
Thank you.
What you experience is a double delete, caused by deleting
display(i.e. the window insidecontainer) after the event loop has been finished. On the one hand, a window container without anything inside isn't of much use. On the other hand, why not letQApplicationdeal with the cleanup? It knows all widgets that are around (->QApplication::allWidgets()) and will destroy them properly. And why deleting stuff afterQApplication::exec()?Why was I doing so? Good question …
Thank you for the advice: I have modified both the C++ and Python version to let
QApplicationdeal with the cleanup. And it solved the problem.Best regards.
-
Y Yoann LE BARS has marked this topic as solved
-
From the Python point of view, the example does not work (wrong imports for QVector3D/Qt3Window). The revised example without cleanup
import sys from PySide6.QtWidgets import QApplication, QMainWindow, QWidget from PySide6.QtGui import QVector3D from PySide6.Qt3DExtras import Qt3DExtras from PySide6.Qt3DCore import Qt3DCore class Simple3DWindow(Qt3DExtras.Qt3DWindow): def __init__(self, parent=None): super().__init__(parent) self._root_entity = Qt3DCore.QEntity() self.setRootEntity(self._root_entity) self.camera().lens().setPerspectiveProjection(45.0, 16.0/9.0, 0.1, 1000.0) self.camera().setPosition(QVector3D(0, 0, 20.0)) self.camera().setViewCenter(QVector3D(0, 0, 0)) def main(): app = QApplication(sys.argv) main_window = QMainWindow() main_window.setWindowTitle("Test QWindowContainer Segfault") main_window.resize(800, 600) display = Simple3DWindow() container = QWidget.createWindowContainer(display) # ← Problem here main_window.setCentralWidget(container) main_window.show() result = QApplication.exec() # QApplication will be automatically destroyed by PySide6 → SEGFAULT return result if __name__ == "__main__": sys.exit(main())does not show any crashes. There are some situations though in PySide, where an explicit synchronous cleanup or shutdown of graphics resources is required. This is then best done in an overridden closeEvent() of the top level window.
Also note that Qt3D is now deprecated.