Bug 524048 - 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)
Summary: drkonqi-coredump-launcher still self-recurses into an unbounded crash loop wh...
Status: RESOLVED FIXED
Alias: None
Product: drkonqi
Classification: Applications
Component: general (other bugs)
Version First Reported In: 6.7.4
Platform: Other Linux
: NOR crash
Target Milestone: ---
Assignee: Plasma Bugs List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2026-08-09 08:47 UTC by Wehrwolfmann
Modified: 2026-08-28 18:06 UTC (History)
3 users (show)

See Also:
Latest Commit:
Version Fixed/Implemented In: 6.7.5
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Wehrwolfmann 2026-08-09 08:47:44 UTC
## 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
`drkonqi-coredump-launcher@.service`:

```
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
`drkonqi-coredump-launcher@.service`.

## 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. `drkonqi-coredump-launcher@.service` 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
Comment 1 LaughingMan 2026-08-18 02:22:36 UTC
baloo_file_extractor runs into what looks like essentially the same problem here. Opened bug 524392 for that but wanted to mention it here as well.
Comment 2 Wehrwolfmann 2026-08-18 08:10:03 UTC
DRAFT for bugs.kde.org/524048 — NOT SENT. Prepared 2026-08-18 by Wehrwolfmann.

---8<--- comment text starts here ---8<---

Thanks for the pointer to bug 524392 — same root state, and it adds what my report
was missing.

That reporter got there by switching sessions (kwin_x11 -> Cinnamon -> kwin_wayland),
not by running a nested compositor. So the stale display environment is not exotic;
an ordinary session switch reaches it. Their variables are only half wrong
(DISPLAY=:1 while WAYLAND_DISPLAY=wayland-0), which is already enough to abort a Qt
GUI process, and graphical-session.target is active throughout.

The difference between the two reports is worth spelling out: baloo_file_extractor
just crashes over and over because something keeps restarting it. drkonqi is the only
component that feeds its own core back into itself, so it is the one that turns a
handful of crashes into hundreds. Stale environment is the trigger; self-recursion is
what makes it unbounded.

I re-checked master today (6.7.80): all three points from comment 0 stand unchanged.
The processor forwards every matching dump without looking at the executable,
tryDrkonqi() has no self-check, main.cpp:248 still builds a QGuiApplication, and the
socket still has TriggerLimitBurst=0 with no StartLimitIntervalSec/StartLimitBurst on
the service. Only the Requisite= line from 522477 landed.

Also worth flagging: bug 517353 was closed FIXED on 2026-08-07, but the
QGuiApplication promotion it introduced is still in place and the FATAL_ERROR
reminder in the top-level CMakeLists still points at that now-closed bug.

My machine has been clean since I fixed the environment by hand (drkonqi 6.7.4,
Qt 6.11.1, systemd 261.2, Wayland). With a sane environment the pipeline is fine — a
kioworker SIGSEGV on 18 Aug produced exactly one launcher instance, which ran drkonqi
and exited normally. Only the stale case has no brake.

Could this move off UNCONFIRMED? Two machines, two distributions, two different routes
into the same state.

---8<--- comment text ends here ---8<---
Comment 3 Harald Sitter 2026-08-24 06:49:45 UTC
Do you want to make a merge request?
Comment 4 Harald Sitter 2026-08-28 10:16:39 UTC
Git commit 8e63a84ddab6884564d9e56ad86e1e508e87a4a0 by Harald Sitter, on behalf of Alexander Berg.
Committed on 28/08/2026 at 10:12.
Pushed by sitter into branch 'master'.

coredump: don't process crashes of our own binaries

A crash of the launcher is picked up by systemd-coredump like any other one,
gets processed, and activates another launcher. When that one crashes as well
the pipeline starts feeding itself. On the reporter's machine it ran at about
2.5 iterations per second and piled up ~2 GB of compressed cores in four and a
half minutes, all from three Spectacle crashes.

Drop dumps whose executable is one of ours before anything gets forwarded. Our
own crashes are still in the journal and in systemd-coredump's storage, they
just don't go around the loop once more.

M  +29   -0    src/coredump/processor/main.cpp

https://invent.kde.org/plasma/drkonqi/-/commit/8e63a84ddab6884564d9e56ad86e1e508e87a4a0
Comment 5 Harald Sitter 2026-08-28 10:21:05 UTC
Git commit c8d69395bea93e913d45ff438564ebd5484221db by Harald Sitter.
Committed on 28/08/2026 at 10:17.
Pushed by sitter into branch 'Plasma/6.7'.

coredump: don't process crashes of our own binaries

A crash of the launcher is picked up by systemd-coredump like any other one,
gets processed, and activates another launcher. When that one crashes as well
the pipeline starts feeding itself. On the reporter's machine it ran at about
2.5 iterations per second and piled up ~2 GB of compressed cores in four and a
half minutes, all from three Spectacle crashes.

Drop dumps whose executable is one of ours before anything gets forwarded. Our
own crashes are still in the journal and in systemd-coredump's storage, they
just don't go around the loop once more.


(cherry picked from commit 8e63a84ddab6884564d9e56ad86e1e508e87a4a0)

Co-authored-by: Alexander Berg <wehrwolfmann@gmail.com>

M  +29   -0    src/coredump/processor/main.cpp

https://invent.kde.org/plasma/drkonqi/-/commit/c8d69395bea93e913d45ff438564ebd5484221db