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

Crash with gcc14 in QLibraryInfo::path(), _q_resolveEntryAndCreateLegacyEngine_recursive, for Qml2Imports

    XMLWordPrintable

Details

    • Linux/Wayland

    Description

      We are seeing a data corruption crash on startup when compiling Qt 6.5.6 against gcc14 on nxp/iMX M8Q. We have a workaround, but the root cause of the error has not been found. TL;DR: See far below for the patch.

      The crash happens when Qt is searching for the QmlImports fallback Qml2Imports entry in the Paths section of a qt.conf .ini file.

      At a glance the patch seems to do nothing; it simply avoids calling the QSettings::value function that takes a second default value argument. The data corruption is seen when QVariant::toString() is called on the returned variant (some realloc/memcpy going on there). The resulting string has a size of 3 (i.e., "qml" one would hope,), but the data of the QString is bad, so accessing str.at(0) or str[0] crashes. This is the backtrace we get with no modifications.

                      "_q_resolveEntryAndCreateLegacyEngine_recursive(QFileSystemEntry&, QFileSystemMetaData&, QAbstractFileEngine*&, bool)()",
                      "QFileSystemEngine::resolveEntryAndCreateLegacyEngine(QFileSystemEntry&, QFileSystemMetaData&)()",
                      "QFileInfo::QFileInfo(QString const&)()",
                      "QDir::isRelativePath(QString const&)()",
                      "QLibraryInfoPrivate::path(QLibraryInfo::LibraryPath, QLibraryInfoPrivate::UsageMode)()",
                      "QLibraryInfo::path(QLibraryInfo::LibraryPath)()",
                      "QQmlImportDatabase::QQmlImportDatabase(QQmlEngine*)()",
                      "QQmlEngine::QQmlEngine(QObject*)()",
                      "<removed>::createSharedQmlEngine()()",
                      "UIMain::exec()()",
                      "main",
                      "__libc_start_call_main",
                      "__libc_start_main",
                      "_start"
      

      Some observations we have made while debugging this issue:

      • The crash seems directly related to QLibraryInfoPrivate::path returning a bad QString.
      • The exact same Qt build on PC linux/wayland, tegra and omap platforms works fine for us (could be by luck).
      • Adding an early return for the key "Qml2Imports" in QSettings::value, that simply returns the defaultValue, does not fix the crash, i.e., this doesn't help:
      QVariant QSettings::value(QAnyStringView key, const QVariant &defaultValue) const
      {
          Q_D(const QSettings);
          if (key == "Qml2Imports")
              return defaultValue;
      
      • However checking for "Qml2Imports" from the outside, and assigning the default value without calling the QSettings::value function, does fix the crash:
      diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
      index 83e131d5912..a78f8b8e46b 100644
      --- a/src/corelib/global/qlibraryinfo.cpp
      +++ b/src/corelib/global/qlibraryinfo.cpp
      @@ -543,8 +543,12 @@ QString QLibraryInfoPrivate::path(QLibraryInfo::LibraryPath p, UsageMode usageMo
                       ret = config->value(li.key, li.defaultValue).toString();
                   } else {
                       QVariant v = config->value(li.key);
      -                if (!v.isValid())
      -                    v = config->value(li.fallbackKey, li.defaultValue);
      +                if (!v.isValid()) {
      +                    if (li.fallbackKey == "Qml2Imports")
      +                        v = li.defaultValue; // no crash
      +                    else
      +                        v = config->value(li.fallbackKey, li.defaultValue);
      +               }
                       ret = v.toString();
                   }
      
      • Overwriting the defaultValue at the very top does not fix the crash; which seems to rule out the rather scary-looking constexpr qtConfEntries in QLibraryInfoPrivate::locationInfo:
      diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
      index 83e131d5912..07161663c9f 100644
      --- a/src/corelib/global/qlibraryinfo.cpp
      +++ b/src/corelib/global/qlibraryinfo.cpp
      @@ -534,6 +534,8 @@ QString QLibraryInfoPrivate::path(QLibraryInfo::LibraryPath p, UsageMode usageMo
               fromConf = true;
       
               auto li = QLibraryInfoPrivate::locationInfo(loc);
      +        if (li.fallbackKey == "Qml2Imports")
      +            li.defaultValue = "qml";
               if (!li.key.isNull()) {
                   QSettings *config = QLibraryInfoPrivate::configuration();
                   Q_ASSERT(config != nullptr);
      
      

      Here's the patch that works around the issue:

      diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
      index 83e131d5912..ff84588ab13 100644
      --- a/src/corelib/global/qlibraryinfo.cpp
      +++ b/src/corelib/global/qlibraryinfo.cpp
      @@ -544,7 +544,9 @@ QString QLibraryInfoPrivate::path(QLibraryInfo::LibraryPath p, UsageMode usageMo
                   } else {
                       QVariant v = config->value(li.key);
                       if (!v.isValid())
      -                    v = config->value(li.fallbackKey, li.defaultValue);
      +                    v = config->value(li.fallbackKey);
      +                if (!v.isValid())
      +                    v = li.defaultValue;
                       ret = v.toString();
                   }
      

      Any help appreciated

      Attachments

        Issue Links

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

          Activity

            People

              cnn Qt Core & Network
              andrhans Andreas Aardal Hanssen
              Votes:
              0 Vote for this issue
              Watchers:
              9 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There are no open Gerrit changes