Subject: bug#42476: closed (Re: Krita fails to start)

From: [email-masked] (GNU bug Tracking System)
Date: Thu, 23 Jul 2020 20:45:01 +0000

Your bug report

#42476: Krita fails to start

which was filed against the guix package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
42476: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=42476
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: Krita fails to start
From: Leo Famulari <[email-masked]>
To: [email-masked]
Date: Thu, 23 Jul 2020 16:44:08 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

This should be fixed with commit
5f63905096e456097fca206f56ce9257f72faf64

Subject: Krita fails to start
From: Leo Famulari <[email-masked]>
To: [email-masked]
Date: Wed, 22 Jul 2020 13:51:41 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

Currently, Krita fails to start after loading its splash screen. It just
hangs forever.

I found this upstream bug report in Qt:

https://bugreports.qt.io/browse/QTBUG-83207

Currently, I'm testing the build of Krita based on the Qt patch in that
bug report.

I've attached my patch.
>From 616b65411505555f71e44618eeb969cf6aa64f02 Mon Sep 17 00:00:00 2001
From: Leo Famulari <[email-masked]>
Date: Wed, 22 Jul 2020 13:47:39 -0400
Subject: [PATCH] gnu: Fix Krita.

* gnu/packages/patches/qtbase-fix-krita-deadlock.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add it.
* gnu/packages/kde.scm (qtbase-for-krita): New variable.
(krita)[inputs]: Replace qtbase with qtbase-for-krita.
---
 gnu/local.mk                                  |   1 +
 gnu/packages/kde.scm                          |  10 +-
 .../patches/qtbase-fix-krita-deadlock.patch   | 110 ++++++++++++++++++
 gnu/packages/qt.scm                           |   1 +
 4 files changed, 121 insertions(+), 1 deletion(-)
 create mode 100644 gnu/packages/patches/qtbase-fix-krita-deadlock.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index a1bd6a644a..6464181548 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1488,6 +1488,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/qrcodegen-cpp-make-install.patch		\
   %D%/packages/patches/qt4-ldflags.patch			\
   %D%/packages/patches/qtbase-absolute-runpath.patch		\
+  %D%/packages/patches/qtbase-fix-krita-deadlock.patch		\
   %D%/packages/patches/qtbase-moc-ignore-gcc-macro.patch	\
   %D%/packages/patches/qtbase-use-TZDIR.patch			\
   %D%/packages/patches/qtscript-disable-tests.patch		\
diff --git a/gnu/packages/kde.scm b/gnu/packages/kde.scm
index 9a80e362b6..9fa8ed7c15 100644
--- a/gnu/packages/kde.scm
+++ b/gnu/packages/kde.scm
@@ -360,6 +360,14 @@ a module for implementing ODF Gantt charts, which are bar charts that
 illustrate project schedules.")
     (license license:gpl2+)))
 
+(define qtbase-for-krita
+  (package
+    (inherit qtbase)
+    (source (origin
+              (inherit (package-source qtbase))
+              (patches (append (origin-patches (package-source qtbase))
+                               (search-patches "qtbase-fix-krita-deadlock.patch")))))))
+
 (define-public krita
   (package
     (name "krita")
@@ -434,7 +442,7 @@ illustrate project schedules.")
        ("openexr" ,openexr)
        ("perl" ,perl)
        ("poppler-qt5" ,poppler-qt5)
-       ("qtbase" ,qtbase)
+       ("qtbase" ,qtbase-for-krita)
        ("qtdeclarative" ,qtdeclarative)
        ("qtmultimedia" ,qtmultimedia)
        ("qtsvg" ,qtsvg)
diff --git a/gnu/packages/patches/qtbase-fix-krita-deadlock.patch b/gnu/packages/patches/qtbase-fix-krita-deadlock.patch
new file mode 100644
index 0000000000..d3554be3c9
--- /dev/null
+++ b/gnu/packages/patches/qtbase-fix-krita-deadlock.patch
@@ -0,0 +1,110 @@
+Fix a deadlock in Krita:
+
+https://bugreports.qt.io/browse/QTBUG-83207
+
+Patch copied from Qt bug tracker:
+
+https://codereview.qt-project.org/c/qt/qtbase/+/296034
+
+From 276fa8383a7535765be7182883ef4aade17ce013 Mon Sep 17 00:00:00 2001
+From: Thiago Macieira <[email-masked]>
+Date: Thu, 02 Apr 2020 12:08:41 -0300
+Subject: [PATCH] QLibrary: fix deadlock caused by fix to QTBUG-39642
+
+Commit ae6f73e8566fa76470937aca737141183929a5ec inserted a mutex around
+the entire load_sys(). We had reasoed that deadlocks would only occur if
+the object creation in instance() recursed into its own instance(),
+which was already a bug. But we had forgotten that dlopen()/
+LoadLibrary() executes initialization code from the module being loaded,
+which could cause a recursion back into the same QPluginLoader or
+QLibrary object. This recursion is benign because the module *is* loaded
+and dlopen()/LoadLibrary() returns the same handle.
+
+[ChangeLog][QtCore][QLibrary and QPluginLoader] Fixed a deadlock that
+would happen if the plugin or library being loaded has load-time
+initialization code (C++ global variables) that recursed back into the
+same QLibrary or QPluginLoader object.
+
+PS: QLibraryPrivate::loadPlugin() updates pluginState outside a mutex
+lock, so pluginState should be made an atomic variable. Once that is
+done, we'll only need locking the mutex to update errorString (no
+locking before loading).
+
+Fixes: QTBUG-83207
+Task-number: QTBUG-39642
+Change-Id: Ibdc95e9af7bd456a94ecfffd160209304e5ab2eb
+Reviewed-by: Volker Hilsheimer <[email-masked]>
+Reviewed-by: David Faure <[email-masked]>
+---
+
+diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
+index ddb053c..be9d92b 100644
+--- a/src/corelib/plugin/qlibrary.cpp
++++ b/src/corelib/plugin/qlibrary.cpp
+@@ -576,9 +576,7 @@
+ 
+     Q_TRACE(QLibraryPrivate_load_entry, fileName);
+ 
+-    mutex.lock();
+     bool ret = load_sys();
+-    mutex.unlock();
+     if (qt_debug_component()) {
+         if (ret) {
+             qDebug() << "loaded library" << fileName;
+diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
+index 017aa97..a5c72f8 100644
+--- a/src/corelib/plugin/qlibrary_unix.cpp
++++ b/src/corelib/plugin/qlibrary_unix.cpp
+@@ -123,6 +123,7 @@
+ 
+ bool QLibraryPrivate::load_sys()
+ {
++    QMutexLocker locker(&mutex);
+     QString attempt;
+     QFileSystemEntry fsEntry(fileName);
+ 
+@@ -213,6 +214,7 @@
+     }
+ #endif
+ 
++    locker.unlock();
+     bool retry = true;
+     Handle hnd = nullptr;
+     for (int prefix = 0; retry && !hnd && prefix < prefixes.size(); prefix++) {
+@@ -273,6 +275,8 @@
+         }
+     }
+ #endif
++
++    locker.relock();
+     if (!hnd) {
+         errorString = QLibrary::tr("Cannot load library %1: %2").arg(fileName, qdlerror());
+     }
+diff --git a/src/corelib/plugin/qlibrary_win.cpp b/src/corelib/plugin/qlibrary_win.cpp
+index 000bf76..ef58724 100644
+--- a/src/corelib/plugin/qlibrary_win.cpp
++++ b/src/corelib/plugin/qlibrary_win.cpp
+@@ -78,6 +78,7 @@
+     //     fileName
+     //
+     // NB If it's a plugin we do not ever try the ".dll" extension
++    QMutexLocker locker(&mutex);
+     QStringList attempts;
+ 
+     if (pluginState != IsAPlugin)
+@@ -95,6 +96,7 @@
+         attempts.prepend(QDir::rootPath() + fileName);
+ #endif
+ 
++    locker.unlock();
+     Handle hnd = nullptr;
+     for (const QString &attempt : qAsConst(attempts)) {
+ #ifndef Q_OS_WINRT
+@@ -115,6 +117,7 @@
+ #ifndef Q_OS_WINRT
+     SetErrorMode(oldmode);
+ #endif
++    locker.relock();
+     if (!hnd) {
+         errorString = QLibrary::tr("Cannot load library %1: %2").arg(
+                     QDir::toNativeSeparators(fileName), qt_error_string());
diff --git a/gnu/packages/qt.scm b/gnu/packages/qt.scm
index 0cb36427a0..e0e71c595d 100644
--- a/gnu/packages/qt.scm
+++ b/gnu/packages/qt.scm
@@ -342,6 +342,7 @@ developers using C++ or QML, a CSS & JavaScript like language.")
 (define-public qtbase
   (package
     (name "qtbase")
+    ;; TODO Remove ((gnu packages kde) qtbase-for-krita) when upgrading qtbase.
     (version "5.14.2")
     (source (origin
              (method url-fetch)
-- 
2.26.2