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

            Bug ID: 524048
           Summary: drkonqi-coredump-launcher still self-recurses into an
                    unbounded crash loop while a graphical session IS
                    active, if the session's display environment is stale
                    (remainder of bug 522477)
    Classification: Applications
           Product: drkonqi
      Version First 6.7.4
       Reported In:
          Platform: Other
                OS: Linux
            Status: REPORTED
          Severity: major
          Priority: NOR
         Component: general
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

## SUMMARY

Bug 522477 ("drkonqi-coredump-launcher crash-loops and fills the disk when
triggered with no
active graphical session") was closed as FIXED by commit b2971200, which adds
one line to
`[email protected]`:

```
Requisite=graphical-session.target
```

That guard only covers the case where there is *no* graphical session. The
underlying defect —
the crash handler is able to process its own crashes, with nothing bounding the
rate — is
untouched, and the loop still occurs whenever a graphical session is perfectly
active but the
*display environment* of the systemd user manager is stale or wrong.

I hit this on drkonqi 6.7.4 (which ships the `Requisite=` line — verified in
the installed unit
file) with `graphical-session.target` active the entire time. Result: **3
crashes of Spectacle
produced 563 SIGABRTs of `drkonqi-coredump-launcher` over the next 4.5
minutes**, and it only
stopped because I fixed the environment by hand. A second, earlier burst on the
same boot brings
the total to 1174 launcher aborts still visible in my journal. The accumulated
compressed core
dumps were on the order of 2 GB when I measured them during the incident (they
have since been
cleaned up, so I can no longer quote an exact figure — the crash counts above
are all directly
verifiable from the journal). No crash dialog and no notification ever
appeared: the component
whose only job is to tell the user about a crash failed silently and
expensively at the same
time.

## HOW THE ENVIRONMENT GETS STALE

Any process that calls `systemctl --user import-environment` or
`dbus-update-activation-environment` inside a running session overwrites
`DISPLAY`,
`WAYLAND_DISPLAY` and `XAUTHORITY` for the whole user manager. In my case a
nested compositor
started for testing did exactly that, leaving the manager pointing at `:1` /
`wayland-1` after
the nested instance was gone. The Plasma session itself continued to run
normally on `:0` /
`wayland-0`, so `graphical-session.target` stayed active.

This does not require a nested compositor to reproduce (see below), and it is
not an exotic
state: anything that mangles the manager's activation environment reaches it.

>From that moment on, **everything started as a systemd user unit** inherits the
stale values and
cannot connect to a display, while anything started from a shell still works.
That includes
Spectacle (`app-org.kde.spectacle.service`, i.e. the Print key) — and it
includes
`[email protected]`.

## STEPS TO REPRODUCE

> ⚠️ **This fills the disk fast** — hundreds of core dumps per minute. Do this 
> only where you can
> afford it, and have the recovery command ready before you start. If you only 
> want to confirm the
> environment half, `systemctl --user mask drkonqi-coredump-launcher.socket` 
> first.
>
> Full disclosure on provenance: the steps below are the minimal distillation 
> of the state I was
> actually in. I reached that state by a different route — a nested compositor 
> started inside my
> live session ran the equivalent of `systemctl --user import-environment`, 
> leaving the manager
> pointing at a display that no longer existed. Everything under OBSERVED 
> RESULT is from that real
> occurrence and is quoted verbatim from my journal; I have deliberately *not* 
> re-run the
> distilled steps, because doing so costs gigabytes and an hour of cleanup, and 
> the mechanism is
> already fully evidenced. Step 1 sets exactly the same manager variables that 
> the compositor set.

1. In a normal, active Plasma Wayland session, poison the user manager's
environment:

   ```
   systemctl --user set-environment DISPLAY=:9 WAYLAND_DISPLAY=wayland-9
   ```

   (`graphical-session.target` stays `active` — check with
   `systemctl --user is-active graphical-session.target`.)

2. Start any Qt GUI application as a user unit, e.g.

   ```
   systemctl --user start app-org.kde.spectacle.service
   ```

   or simply press the Print key.

3. Watch `journalctl --user -f` and `coredumpctl list`.

**Recovery:**

```
systemctl --user set-environment DISPLAY=:0 WAYLAND_DISPLAY=wayland-0
XAUTHORITY=<your value>
dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY XAUTHORITY
```

The loop stops in the same second.

## OBSERVED RESULT

Spectacle aborts (expected — no display). Then the launcher aborts in exactly
the same way, and
its own core re-enters the pipeline, forever:

```
22:08:27 spectacle[1016505]: Failed to create wl_display (No such file or
directory)
22:08:27 spectacle[1016505]: could not connect to display :1
22:08:27 systemd-coredump[1016507]: Process 1016505 (spectacle) of user 1000
terminated abnormally with signal 6/ABRT, processing...
22:08:27 systemd[1]: Started Pass systemd-coredump journal entries to relevant
user for potential DrKonqi handling.
22:08:28 drkonqi-coredump-processor[1016511]: "/usr/bin/spectacle" 1016505
"/var/lib/systemd/coredump/core.spectacle.1000...zst"
22:08:28 systemd[1326]: Started Launch DrKonqi for a systemd-coredump crash
(PID 1016511/UID 0).
22:08:28 drkonqi-coredump-launcher[1016538]: Failed to create wl_display (No
such file or directory)
22:08:28 drkonqi-coredump-launcher[1016538]: could not connect to display :1
22:08:28 drkonqi-coredump-launcher[1016538]: This application failed to start
because no Qt platform plugin could be initialized.
22:08:28 systemd-coredump[1016540]: Process 1016538 (drkonqi-coredum) of user
1000 terminated abnormally with signal 6/ABRT, processing...
22:08:28 systemd[1]: Started Pass systemd-coredump journal entries to relevant
user for potential DrKonqi handling.
   ... and around again, ~2.5 iterations per second
```

The systemd instance counter climbs by one per launcher abort. For the burst
above it went from
`drkonqi-coredump-launcher@1976-...` to `@2538-...`:

```
$ journalctl -b --since "22:00" | grep -c 'Process .*(drkonqi-coredum).*dumped
core'
563          # from 3 Spectacle crashes, between 22:08:28 and 22:13:00

$ journalctl -b | grep -c 'Process .*(drkonqi-coredum).*dumped core'
1174         # total still visible in the journal, two bursts

$ journalctl -b | grep 'dumped core' | grep -v drkonqi-coredum
... 3 lines, all Spectacle
```

Note the ratio: **three crashes of one application, 563 crashes of the crash
handler.** Nothing
in the pipeline notices that it is processing its own output.

`graphical-session.target` was `active` throughout
(`ActiveEnterTimestamp=Fri 2026-08-07 20:46:17 CEST`), so
`Requisite=graphical-session.target`
was satisfied every single time.

## EXPECTED RESULT

The crash handler must not be able to loop on its own failure, in any
environment. One bad
application crash should produce at most a bounded, small number of handler
invocations.

## ANALYSIS

Three independent things have to be true for the loop to run. All three are
true today; fixing
any one of them breaks it, and I think all three are worth fixing.

**1. There is no self-exclusion anywhere in the pipeline.**

Nothing in `src/` skips a dump whose `COREDUMP_EXE` is drkonqi's own launcher
(or drkonqi, or
`drkonqi-coredump-gui`, or the processor). `src/coredump/processor/main.cpp`
forwards every dump
for the matching UID to the user socket, and `tryDrkonqi()` in
`src/coredump/launcher/main.cpp` has no such check either. So the component
that handles crashes
handles its own crashes. This is the engine of the loop.

The reporter of 522477 asked for precisely this in their EXPECTED RESULT —
*"the pipeline should
never reprocess the launcher's own crashes. A coredump handler must not be able
to loop on its
own failure"* — and it was not implemented; only the unit condition was added.

**2. The launcher aborts on its very first statement when there is no usable
display.**

`src/coredump/launcher/main.cpp:248`:

```cpp
int main(int argc, char **argv)
{
    QGuiApplication app(argc, argv);
```

Qt's `qFatal()` inside the QPA setup calls `abort()`, so this is a SIGABRT with
a core dump, not
an exit. The launcher never reaches its socket read, its metadata handling or
its notifier
fallbacks.

This is the temporary promotion from `QCoreApplication` made in f1552403d5 for
bug 517353
(KNotification's `stripRichText` needing QtGui), which the code itself marks as
provisional —
`CMakeLists.txt` carries a tripwire:

```cmake
if(${QT_MIN_VERSION} VERSION_GREATER_EQUAL "6.12.0")
    message(FATAL_ERROR "Turn drkonqi-coredump-launcher into a
qcoreapplication! https://bugs.kde.org/show_bug.cgi?id=517353";)
endif()
```

Comment #21 on 517353 predicted this outcome at the time ("something triggered
by systemd service
should not depend on Gui in the first place and this change may cause it to
crash sooner"), and
comment #22 (2026-08-07) reports Ubuntu still seeing crashes from it.

**3. Nothing limits the rate.**

`drkonqi-coredump-launcher.socket` explicitly disables systemd's own
protection:

```
# Disable trigger limit for the benefit of older systemds
# TODO: remove in favor of PollLimitBurst mechanism once systemd 255 is in
ubuntu LTS
TriggerLimitBurst=0
```

The default for an `Accept=yes` socket is 200 activations per 2 s; `0` means no
limit at all.
`MaxConnections=16` caps *concurrency*, not rate — a strictly serial loop like
this one never
touches it. `[email protected]` sets `Restart=no` but has no
`StartLimitIntervalSec=`/`StartLimitBurst=`. So there is no ceiling anywhere.

The TODO's own condition is now met: Ubuntu 24.04 LTS ships systemd
255.4-1ubuntu8.

## SUGGESTED FIXES

In order of how much I would trust them:

**A. Self-exclusion in the pipeline (the real fix).** Drop dumps whose
executable is one of
drkonqi's own binaries, in the processor's `newDump` handler (cheapest place —
it already has
`dump.exe`) or at the top of `tryDrkonqi()`. A crash handler that structurally
cannot handle its
own crash cannot loop, whatever else goes wrong with the environment. This also
protects against
future crashes of the launcher for reasons that have nothing to do with the
display.

**B. Do not abort when there is no display.** Either complete the planned
revert to
`QCoreApplication`, or, while the QtGui promotion stands, degrade instead of
aborting — check for
a usable QPA platform before constructing `QGuiApplication` and either fall
back to
`QT_QPA_PLATFORM=offscreen` (enough for `stripRichText`) or log and `exit(0)`.
Exiting cleanly
also means no core dump is produced, so nothing re-enters the pipeline.

**C. Restore rate limiting on the socket.** Remove `TriggerLimitBurst=0` (back
to the 200/2 s
default) and/or add `PollLimitIntervalSec=`/`PollLimitBurst=`, as the file's
own TODO intends. This
turns an unbounded loop into a bounded burst even if A and B are somehow
bypassed, and it should
also help bug 506167, where you noted throttling is needed for the login-time
pickup path.

## RELATED

- Bug 522477 — same loop, narrower trigger; fixed only for the "no graphical
session" case.
- Bug 517353 — origin of the `QGuiApplication` promotion; comment #21 predicted
this,
  comment #22 (2026-08-07) reports it still biting Ubuntu users.
- Bug 506167 — launcher socket saturation (`Too many incoming connections
(16)`); same missing
  throttling, different entry point.

If you would rather treat this as a reopen of 522477 than a new report, I am
happy for it to be
moved — I filed it separately only because 522477's title and fix are scoped to
the case where
no graphical session exists, which is not what happens here.

## SOFTWARE/OS VERSIONS

- Operating System: CachyOS (Arch-based)
- KDE Plasma Version: 6.7.x, drkonqi 6.7.4
- Qt Version: 6.11.1
- systemd 261.2
- Session: Wayland

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

Reply via email to