Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Mar 2025 17:24:42 +0000
From:      bugzilla-noreply@freebsd.org
To:        threads@FreeBSD.org
Subject:   [Bug 285612] Qt thread deadlocks on destruction after fork()
Message-ID:  <bug-285612-13406@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D285612

            Bug ID: 285612
           Summary: Qt thread deadlocks on destruction after fork()
           Product: Base System
           Version: CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: threads
          Assignee: threads@FreeBSD.org
          Reporter: arrowd@FreeBSD.org

Created attachment 258950
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=3D258950&action=
=3Dedit
Testcase program

This bug was haunting me since Qt 5, but only now I was able to derive a
minimal testcase. I tried to replicate what Qt does to minimize even more, =
but
failed to do that - too much complex stuff contributes to this bug: forking,
threads, thread-local storage and __cxa_atexit.

When the test program is ran as

./a.out fork stuff

the program successfully terminates. However, running it as

./a.out stuff fork

makes the child hang in QDBusConnectionManager::~QDBusConnectionManager [1]=
. A
bit of debugging lead me to [2], which is an exceptionally complex piece of
code. By putting prints here and there I found out that the function passed
into pthread_cleanup_push in [3] does not get called in the 'stuff-fork' ca=
se.
Not sure if it's a problem or a symptom.

'fork-stuff':
set_thread_data(non-null)
destroy_current_thread_data
set_thread_data(non-null)
pthread_cleanup
destroy_current_thread_data
destroy_current_thread_data
set_thread_data(null)

'stuff-fork':
set_thread_data(non-null)
set_thread_data(non-null)

Since debugging this issue would require building Qt with debugging enabled,
here's a recipe on how to get a debugging env with Poudriere:

echo WITH_DEBUG_PORTS=3Ddevel/qt6-base >> /usr/local/etc/poudriere.d/make.c=
onf
poudriere testport -j yourjail -p yourports -i devel/qt6-base

Then inside the jail:
fetch https://arrowd.name/t.cpp
head t.cpp (to get a c++ command line to compile the program

To apply some changes to Qt itself:

$EDITOR /wrkdirs/usr/ports/devel/qt6-base/work/...
make WITH_DEBUG=3Dyes restage reinstall

[1]
https://github.com/qt/qtbase/blob/v6.8.2/src/dbus/qdbusconnectionmanager.cp=
p#L117
[2]
https://github.com/qt/qtbase/blob/v6.8.2/src/corelib/thread/qthread_unix.cp=
p#L82
[3]
https://github.com/qt/qtbase/blob/v6.8.2/src/corelib/thread/qthread_unix.cp=
p#L338

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-285612-13406>