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

A Q_COREAPP_STARTUP_FUNCTION is called 2x if in lib linked by platform plugin

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P3: Somewhat important
    • None
    • 5.6.0
    • Core: Other
    • None

    Description

      If a QPlatformIntegration plugin links directly or indirectly a library which uses Q_COREAPP_STARTUP_FUNCTION in its code, this will result in the function registered by that to be called 2x (unless the library is already loaded before, e.g. by being linked from the executable).

      This happens because qAddPreRoutine() (as used by Q_COREAPP_STARTUP_FUNCTION) has the logic
      if (QCoreApplication::instance())
      p();
      list->prepend(p); // in case QCoreApplication is re-created, see qt_call_pre_routines
      Just, it happens that the platform plugins are loaded in the middle of QCoreApplicationPrivate::init() between setting the app instance (QCoreApplication::self) and executing all the startup hooks (qt_call_pre_routines()), because createEventDispatcher(); is overriden by QGuiApplicationPrivate and that one calls createPlatformIntegration();.
      Thus qAddPreRoutine() will execute the registered function because the instance is set, but so also will qt_call_pre_routines(), because the function is in the list.

      Most easy fix is to simply forbid platform integration plugins to make use of that macro in any code it (re)uses. But that would complicate life for any Qt-based platform, as their platform plugin surely wants to reuse the existing Qt-based shared libs.

      A possible solution might be to have another flag named perhaps QCoreApplicationPrivate::preroutines_executed which would be set to true for the time span when qAddPreRoutine() should execute the function itself.
      (I was to propose to reuse QCoreApplicationPrivate::is_app_running for that, but that relies on QT_NO_QOBJECT and also could qt_startup_hook(); and qtHookData trigger any additional plugin loading with the same initial problem the platformintegration plugin brings, so a dedicated flag might safe more trouble).
      To be more safe, perhaps qt_call_pre_routines() should also make a copy of the list before starting to execute all the functions. After all any of those functions could result in another plugin being loaded which again might result in Q_COREAPP_STARTUP_FUNCTION being applied.

      In summary, the concept of preroutines is fragile to plugins in general and needs some proper protection.

      Real world scenario which motivated this bug report:
      the KDE Plasma platform plugin links to the library libKF5I18n which uses Q_COREAPP_STARTUP_FUNCTION. That lib is used for gettext-based translation and used by most software from KDE, incl. Plasma.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            thiago Thiago Macieira
            kossebau Friedrich W. H. Kossebau
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes