rbreu / beeref

BeeRef Reference Image Viewer
GNU General Public License v3.0
531 stars 40 forks source link

Fix crash on exit by uninstalling Qt message handler #89

Closed Smjert closed 10 months ago

Smjert commented 10 months ago

If we don't uninstall the message handler before exiting, if Qt has messages to send after the python application side has been destroyed, Qt will crash trying to call the python interpreter.

One examples of such messages are the ones that are enabled through QT_DEBUG_PLUGINS, which report the libraries that get unloaded.

Crash stacktrace:

Thread 1 (Thread 0x7ffff7e93740 (LWP 105732) "python3"):
#0  0x00007ffff7a94770 in new_threadstate (interp=0x0) at Python/pystate.c:809
#1  0x00007ffff7a9473a in PyThreadState_New (interp=<optimized out>) at Python/pystate.c:863
#2  0x00007ffff7933c3e in PyGILState_Ensure () at Python/pystate.c:1697
#3  0x00007ffff68aa85c in qtcore_MessageHandler(QtMsgType, QMessageLogContext const&, QString const&) (type=QtDebugMsg, context=..., msg=...) at /usr/src/debug/pyqt6/PyQt6-6.6.1/sip/QtCore/qlogging.sip:214
#4  0x00007ffff6302204 in qt_message_print(QtMsgType, QMessageLogContext const&, QString const&) (msgType=QtDebugMsg, context=..., message=...) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.6.1/src/corelib/global/qlogging.cpp:1984
#5  0x00007ffff6310c44 in qt_message_output(QtMsgType, QMessageLogContext const&, QString const&) (message=..., context=..., msgType=QtDebugMsg) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.6.1/src/corelib/global/qlogging.cpp:2038
#6  QDebug::~QDebug() (this=0x7fffffffde30, this=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.6.1/src/corelib/io/qdebug.cpp:166
#7  QDebug::~QDebug() (this=0x7fffffffde30, this=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.6.1/src/corelib/io/qdebug.cpp:160
#8  0x00007ffff65d24d8 in QLibraryPrivate::unload(QLibraryPrivate::UnloadFlag) [clone .constprop.0] (this=this@entry=0x555555b38360, flag=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.6.1/src/corelib/plugin/qlibrary.cpp:548
#9  0x00007ffff6597a14 in QLibraryStore::cleanup() () at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.6.1/src/corelib/plugin/qlibrary.cpp:357
#10 qlibraryCleanup () at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.6.1/src/corelib/plugin/qlibrary.cpp:380
#11 (anonymous namespace)::qlibraryCleanup_dtor_class_::~qlibraryCleanup_dtor_class_() (this=<optimized out>, this=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.6.1/src/corelib/plugin/qlibrary.cpp:382
#12 0x00007ffff765ecc6 in __run_exit_handlers (status=status@entry=0, listp=0x7ffff77f6680 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true, run_dtors=run_dtors@entry=true) at exit.c:111
#13 0x00007ffff765ee10 in __GI_exit (status=status@entry=0) at exit.c:141
#14 0x00007ffff793aae7 in Py_Exit (sts=0) at Python/pylifecycle.c:2944
#15 0x00007ffff7acc33b in handle_system_exit () at Python/pythonrun.c:771
#16 0x00007ffff7acc13c in _PyErr_PrintEx (set_sys_last_vars=1, tstate=0x7ffff7d89378 <_PyRuntime+166328>) at Python/pythonrun.c:781
#17 PyErr_PrintEx (set_sys_last_vars=1) at Python/pythonrun.c:876
#18 0x00007ffff7935d5a in PyErr_Print () at Python/pythonrun.c:882
#19 _PyRun_SimpleFileObject (fp=<optimized out>, filename=<optimized out>, closeit=<optimized out>, flags=0x7fffffffe078) at Python/pythonrun.c:446
#20 0x00007ffff7aca958 in _PyRun_AnyFileObject (fp=0x55555555a470, filename=0x7ffff7612ef0, closeit=1, flags=0x7fffffffe078) at Python/pythonrun.c:79
#21 0x00007ffff7ac51f8 in pymain_run_file_obj (skip_source_first_line=0, filename=0x7ffff7612ef0, program_name=0x7ffff75c04e0) at Modules/main.c:360
#22 pymain_run_file (config=0x7ffff7d6f3c0 <_PyRuntime+59904>) at Modules/main.c:379
#23 pymain_run_python (exitcode=0x7fffffffe070) at Modules/main.c:601
#24 Py_RunMain () at Modules/main.c:680
#25 0x00007ffff7a8e79b in Py_BytesMain (argc=<optimized out>, argv=<optimized out>) at Modules/main.c:734
#26 0x00007ffff7645cd0 in __libc_start_call_main (main=main@entry=0x555555555120 <main>, argc=argc@entry=2, argv=argv@entry=0x7fffffffe2c8) at ../sysdeps/nptl/libc_start_call_main.h:58
#27 0x00007ffff7645d8a in __libc_start_main_impl (main=0x555555555120 <main>, argc=2, argv=0x7fffffffe2c8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe2b8) at ../csu/libc-start.c:360
#28 0x0000555555555045 in _start ()
codecov-commenter commented 10 months ago

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Comparison is base (6f6afa3) 97.19% compared to head (5059299) 97.19%.

:exclamation: Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #89 +/- ## ======================================= Coverage 97.19% 97.19% ======================================= Files 25 25 Lines 2959 2960 +1 ======================================= + Hits 2876 2877 +1 Misses 83 83 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

rbreu commented 10 months ago

Thanks a lot!