https://bugs.kde.org/show_bug.cgi?id=526441

            Bug ID: 526441
           Summary: KConfigIni::parseConfig loops forever when
                    QFile::readLineInto() fails (kded6 busy-loop, journald
                    flood)
    Classification: Frameworks and Libraries
           Product: frameworks-kconfig
      Version First 6.30.0
       Reported In:
          Platform: CachyOS
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: general
          Assignee: [email protected]
          Reporter: [email protected]
                CC: [email protected]
  Target Milestone: ---

KConfigIniBackend::parseConfig() has an unbounded loop.

The streaming loop from f7cf15af ("KConfigIni: parseConfig simplify
implementation"):

https://invent.kde.org/frameworks/kconfig/-/blob/v6.30.0/src/core/kconfigini.cpp#L85
(github right to the line
https://github.com/KDE/kconfig/blob/v6.30.0/src/core/kconfigini.cpp#L85-L90 )

      while (!file->atEnd() && errorCount < MAX_ERRORS) {
          auto res = file->readLineInto(&buffer, maximumSizeWithoutNewLine);
          if (!res) {
              qCWarning(KCONFIG_CORE_LOG) << "Couldn't find a single line in "
...
                                          << " after reading" <<
maximumSizeWithoutNewLine << "bytes.";
          }
          ...
      }

exits only when QFile::atEnd() becomes true or errorCount reaches MAX_ERRORS.
The if (!res) branch does neither (no break, no errorCount++), so if atEnd()
stays false while readLineInto() keeps failing, this never terminates.

QFileDevice::atEnd() can return false at EOF via its last fallback:
 
https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/io/qfiledevice.cpp?h=v6.11.2#n367
      return bytesAvailable() == 0;
and for non-sequential devices QIODevice::bytesAvailable() is
 
https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/io/qiodevice.cpp?h=v6.11.2#n966
      return qMax(size() - d->pos, qint64(0));
i.e. live stat() size versus Qt's internal position. Whenever that stays > 0
while reads return 0/-1 (internal position desync, or a transient/persistent
read error on a file whose stat size is non-zero), atEnd() is stuck false and
the loop is unbounded — each iteration logs the warning.

--

- kded6 pinned at ~10-20% CPU; journald at ~8%, suppressing
  "Suppressed ~2.0e7 messages from [email protected]" every 30s.
- /proc/<pid>/io: syscr = 1.2e10 vs rchar = 10 MB (~1.3M read(2)/s returning
0).
- /proc/<pid>/fdinfo/0: pos == file size (EOF); the file itself is valid
  (md5 of the fd matches the on-disk file). No filesystem/I-O errors in dmesg.
- Only a kded6 restart clears it; it recurred after suspend/resume (2/2 boots
  that suspended, 0/4 that did not)

Introduced by f7cf15af (2026-01-12), following the streaming rewrite
6d23c7f5 (2025-11-14); still present on master. Shipped since KF 6.23.0

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to