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

Krzysztof Łastowski <[email protected]> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|BACKTRACE                   |---
             Status|NEEDSINFO                   |CONFIRMED

--- Comment #6 from Krzysztof Łastowski <[email protected]> ---
Follow-up on the crash side of this report (the symlink-clobbering behaviour is
now tracked separately in bug 525445).

I couldn't get a live backtrace (see attempts below), but I think I found the
actual cause by reading the source, and I don't think a backtrace would add
much beyond it.

Root cause (probably): kcms/kfontinst/dbus/FontInst.cpp, FontInst::FontInst():

    QDBusConnection bus = QDBusConnection::sessionBus();

    if
(!bus.registerService(QLatin1String(OrgKdeFontinstInterface::staticInterfaceName())))
{
        ::exit(-1);
    }
    if (!bus.registerObject(FONTINST_PATH, this)) {
        ::exit(-1);
    }

::exit(-1) is exit code 255 on Linux (truncated to 8 bits) - which matches the
status=255/EXCEPTION in every occurrence I have. So this isn't a memory-safety
crash at all; it's a deliberate bailout when the daemon can't claim the
org.kde.fontinst service name (or its D-Bus object) on the session bus.

That lines up with the journal pattern from my last comment:

  2026-09-07T14:35:31+01:00 systemsettings[38010]: Service org.kde.fontinst not
registered, starting ".../libexec/fontinst"
  2026-09-07T14:35:31+01:00 systemd[1890]:
dbus-:[email protected]: Main process exited, code=exited,
status=255/EXCEPTION

My reading: systemsettings checks whether the service is registered, sees that
it isn't, and activates a new instance - but if the previous fontinst instance
hasn't fully released the bus name yet (or something else transiently holds
it), registerService() on the new instance fails and it immediately exits
instead of retrying. A TOCTOU race between the "is it registered" check and the
new instance's own registration, not a crash in the traditional sense.

Why I don't think a backtrace helps: a backtrace captured at this exact point
would just show these two exit(-1) call sites - there's no deeper stack to
inspect, since it's a deliberate early-return, not a fault. What would actually
help is knowing why registerService() failed at that moment (stale name
ownership on the broker side, a policy issue, something else) - which needs
D-Bus broker-side instrumentation, not a backtrace of fontinst itself.

What I tried to reproduce it live (before finding the above): ran fontinst
under gdb (unstripped binary, no debuginfod needed) with breakpoints on
exit/_exit conditioned on exit code 255 and catchpoints on SIGABRT/SIGSEGV,
across three attempts - a single KCM open, and twice deliberately killing one
instance and immediately starting a replacement under gdb to force a rapid
re-registration, timed to match the ~2-minute-apart pattern above. All three
exited cleanly (exit(0), presumably the idle-timeout). Given the source now,
that tracks - I was trying to force a timing race by hand, which is inherently
hard to land exactly, and each attempt also reproduced the symlink-clobbering
side effect (525445), so I didn't want to keep hammering on it blindly.

Given the above, I'd suggest looking at whether
registerService()/registerObject() failing should retry with a short delay
instead of immediately calling exit(-1) - that would likely fix both the
"crash" and the noise in the logs, without needing a specific reproduction.

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

Reply via email to