Bug 505649

Summary: Okular crashes on shutdown inconsistently if closed immediately after opening a PDF
Product: [Applications] okular Reporter: Michael Pyne <mpyne>
Component: generalAssignee: Okular developers <okular-devel>
Status: REPORTED ---    
Severity: crash    
Priority: NOR    
Version First Reported In: unspecified   
Target Milestone: ---   
Platform: Compiled Sources   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: Okular crash backtrace with debug symbols

Description Michael Pyne 2025-06-16 03:11:09 UTC
Created attachment 182298 [details]
Okular crash backtrace with debug symbols

SUMMARY

Okular crashes on shutdown for me, seemingly due to a timing issue on destruction of the U/I shell when lambdas are in use. I have a patch that works for me but may not be the best way to fix.

STEPS TO REPRODUCE
1.  Open Okular
2.  Open a PDF from the welcome screen
3.  Immediately close Okular by clicking the 'X' on the titlebar.

OBSERVED RESULT
Okular shuts down, but crashes.

kde@midna ~ $ okular
QObject::disconnect: wildcard call disconnects from destroyed signal of KToggleAction::mouse_toggle_annotate
QObject::disconnect: wildcard call disconnects from destroyed signal of KToggleAction::show_leftpanel
KCrash: Application 'okular' crashing... crashRecursionCounter = 2
Segmentation fault (core dumped)

EXPECTED RESULT

Okular shuts down with no crash.

SOFTWARE/OS VERSIONS
Okular: Compiled from git: v24.20.85-604-g696bb55ae
Linux: 6.16.0-rc1
KDE Plasma Version: 6.4 dev
KDE Frameworks Version: 6.14.0
Qt Version: 6.8.3 (qt-copy 6.8 branch)

ADDITIONAL INFORMATION

This patch fixes the crash for me.

```diff
diff --git a/shell/shell.cpp b/shell/shell.cpp
index ac9916282..c4beab21e 100644
--- a/shell/shell.cpp
+++ b/shell/shell.cpp
@@ -251,7 +251,7 @@ Shell::Shell(const QString &serializedOptions)
         m_sidebar->setObjectName(QStringLiteral("okular_sidebar"));
         m_sidebar->setContextMenuPolicy(Qt::ActionsContextMenu);
         m_sidebar->setWindowTitle(i18n("Sidebar"));
-        connect(m_sidebar, &QDockWidget::visibilityChanged, this, [this](bool visible) {
+        connect(m_sidebar, &QDockWidget::visibilityChanged, m_centralStackedWidget, [this](bool visible) {
             // sync sidebar visibility with the m_showSidebarAction only if welcome screen is hidden
             if (m_showSidebarAction && m_centralStackedWidget->currentWidget() != m_welcomeScreen) {
                 m_showSidebarAction->setChecked(visible);
```

This leads me to believe that the issue is due to the Shell's m_sidebar holding a pointer to a sibling U/I element (the centralStackedWidget). If during automatic QObject destruction during shutdown, events happen in this order:

1. the centralStackedWidget is deleted
2. the m_sibling receives the QDockWidget::visibilityChanged signal
3. the m_sibling is deleted

Then the Qt event loop processing won't know to ignore the event's lambda handler, as the signal/slot connection is keyed to the overarching parent Shell (which won't be finally deleted until all its children are deleted).

There are probably various other ways to address the issue but this at least makes the crash go away from me. A better solution is probably to manually delete all the Shell's U/I children in a specific order in Shell's destructor rather than relying on Qt's auto-destruction, especially if there are other possible sibling-to-sibling events involving stored pointers.