Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-53031

Windows application deadlocks on exit when unloading a library connected to DBus

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P2: Important
    • Resolution: Done
    • Affects Version/s: 5.6.0, 5.6.1, 5.8.0, 5.9.0 Alpha
    • Fix Version/s: 5.9.0 Beta 2
    • Component/s: D-Bus
    • Labels:
      None
    • Environment:
      Windows 7 with MSVC2015 and MinGW 4.9.2
    • Commits:
      fecaa6aae83a3ffa8f1fd41c5aa8275a1bfa7c9b, 9449325f2b234981a2ecc1b0a0bd6ec74f30ff6c

      Description

      The issue explained below might be an edge case, but is a regression 5.5 -> 5.6.
      When loading a dynamic library at runtime with QLibrary and calling a function which initializes QDBusConnectionManager, the application dead locks when trying to unload the library again. The use case for such architecture is plugin libraries, loaded at runtime and using QtDBus connections.

      Attached is a small sample reproducing the issue. When running 'app', it loads the library 'lib' and resolves the method 'openDBus'. This method connects to the session bus and disconnects again. After 500 ms, app tries to unload 'lib' again causing the dead lock.

      The full stack trace is attached. Snippets are presented below.
      Main thread is waiting for QDBusConnectionManager thread to be finished.

      0035d4e8 75ce15ce ntdll!NtWaitForSingleObject+0x15
      0035d554 75d61194 KERNELBASE!WaitForSingleObjectEx+0x98
      0035d56c 75d61148 kernel32!WaitForSingleObjectExImplementation+0x75
      0035d580 663b23eb kernel32!WaitForSingleObject+0x12
      0035d5c8 0fcaba54 Qt5Cored!QThread::wait(unsigned long time = 0xffffffff)+0xfb [c:\projects\qt\qt5\qtbase\src\corelib\thread\qthread_win.cpp @ 598]
      0035d5d8 0fcae64f Qt5DBusd!QDBusConnectionManager::~QDBusConnectionManager(void)+0x24 [c:\projects\qt\qt5\qtbase\src\dbus\qdbusconnection.cpp @ 162]
      

      however, the QDBusConnectionManager thread is locked with this stack trace:

      00f8fd24 776fe70a ntdll!NtWaitForSingleObject+0x15
      00f8fd88 776fe5ee ntdll!RtlpWaitOnCriticalSection+0x13e
      00f8fdb0 776ec11a ntdll!RtlEnterCriticalSection+0x150
      00f8fdf0 75ce1956 ntdll!LdrUnloadDll+0x2a
      00f8fe04 005b87ee KERNELBASE!FreeLibraryAndExitThread+0x28
      00f8fe1c 005b8cae ucrtbased!`anonymous namespace'::thread_parameter_free_policy::operator()+0xee
      00f8fe28 005b8684 ucrtbased!_endthreadex+0xe
      00f8fe6c 75d6338a ucrtbased!_register_onexit_function+0x1f4
      00f8fe78 776e9902 kernel32!BaseThreadInitThunk+0xe
      00f8feb8 776e98d5 ntdll!__RtlUserThreadStart+0x70
      00f8fed0 00000000 ntdll!_RtlUserThreadStart+0x1b
      

      I have no good idea whats going on and which library is unloaded from the dbus thread. http://stackoverflow.com/questions/10441048/exit-thread-upon-deleting-static-object-during-unload-dll-causes-deadlock explains a very similar thing. LdrUnloadDll is called from both threads, the main one holding the lock and the second one waiting for it. So I suspect something similar is happening here. My first assumption was that libdbus is unloaded from QDBusConnectionManager thread before exiting, however this also happens even if libdbus-1 is not even available. So I have no clue which library is being unloaded in the stack trace.

      As soon as the two QDBusConnection calls in lib.cpp are commented, the application quits without issues.

      Would a potential solution be to add a shorter timeout to QThread::wait? E.g.

      QDBusConnectionManager::~QDBusConnectionManager()
      {
          quit();
          wait(1000);
      }
      

        Attachments

        1. qtbug53031.zip
          2 kB
        2. stacktrace.txt
          12 kB
        3. windows-thread-exit.zip
          1 kB

          Issue Links

          For Gerrit Dashboard: QTBUG-53031
          # Subject Branch Project Status CR V

            Activity

              People

              • Assignee:
                thiago Thiago Macieira
                Reporter:
                rolandwinklmeier Roland Winklmeier
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Gerrit Reviews

                  There are no open Gerrit changes