https://bugs.kde.org/show_bug.cgi?id=526995
Bug ID: 526995
Summary: Previews of a video that is still being written
(torrent) spawn dozens of ffmpegthumbnailer processes
and freeze CPU and disk: regression of the 1000 ms ->
100 ms debounce in Dolphin 20.08 + orphaned
thumbnailer processes in KIO
Classification: Applications
Product: dolphin
Version First 26.08.2
Reported In:
Platform: CachyOS
OS: Linux
Status: REPORTED
Severity: major
Priority: NOR
Component: view-engine: general
Assignee: [email protected]
Reporter: [email protected]
CC: [email protected]
Target Milestone: ---
SUMMARY
When a folder that contains a large video file which is still being written is
open in Dolphin with previews enabled (the default), Dolphin regenerates that
file's thumbnail over and over for as long as the file is being written. With a
multi-gigabyte video this goes far beyond "high CPU usage": dozens of
ffmpegthumbnailer processes are started as children of the dolphin process, all
CPU cores and the disk are saturated, and the whole desktop freezes within
seconds. Even the task manager I used to kill the processes (Mission Center)
crashed with SIGABRT. Load average right after the storm was about 35 on an
8-thread CPU. The processes keep running after Dolphin is closed.
This has been reported repeatedly since 2021 and every report ended without a
root cause:
- https://bugs.kde.org/show_bug.cgi?id=467774 (kio-extras, CONFIRMED, open
since 2023, no developer comment)
- https://bugs.kde.org/show_bug.cgi?id=457532 (kio-extras, CONFIRMED, open
since 2022, no developer comment)
- https://bugs.kde.org/show_bug.cgi?id=508839 (dolphin, auto-closed as
WORKSFORME by the bug janitor although the reporter answered the question)
- https://bugs.kde.org/show_bug.cgi?id=431513 (kio-extras, closed WORKSFORME)
- https://bugs.kde.org/show_bug.cgi?id=357693 (dolphin, 2016, closed by the
reporter after removing ffmpegthumbs)
- https://bugs.kde.org/show_bug.cgi?id=295031 (dolphin, 2012, FIXED at the time
with a ~2 s debounce, which later regressed, see below)
- https://bugs.kde.org/show_bug.cgi?id=523498 (kio-extras, same class of
problem for PDF/Ghostscript: thumbnailer processes are not terminated on cancel
and survive Dolphin)
Below are a reliable way to reproduce it, the conditions under which it does
NOT reproduce (which is why it kept being closed as WORKSFORME), the complete
mechanism traced in the source of the current releases with links, the commit
that introduced the regression, and suggested fixes.
REAL-WORLD SCENARIO
I download a TV series by torrent: 5 episodes, UHD Blu-ray remux, about 150 GB
total, 27-30 GB per .mkv. In qBittorrent I enable "Download in sequential
order" so that I can start watching the beginning of episode 1 while the rest
of it and the other episodes are still downloading. Streaming while downloading
is exactly what sequential mode is for.
As soon as I open that folder in Dolphin to start the first episode, the system
dies: dozens of ffmpegthumbnailer processes appear under dolphin in the process
tree, CPU and disk go to 100%, and the desktop locks up. With a single video
file the same thing happens on a smaller scale.
STEPS TO REPRODUCE
1. Dolphin with previews enabled (default), icon view. Have the
ffmpegthumbnailer package installed (it ships
/usr/share/thumbnailers/ffmpegthumbnailer.thumbnailer, which KIO runs through
StandardThumbnailJob). In my setup ffmpegthumbs is installed as well; the
processes that piled up were ffmpegthumbnailer, as children of dolphin.
2. In qBittorrent with default settings (in particular "Append .!qB extension
to incomplete files" stays OFF, which is the default), add a torrent with a
large video file. A UHD BD remux .mkv of about 40 GB is ideal; any 20-40 GB
remux works. A season pack with several such files makes it much worse.
3. In the torrent's context menu enable "Download in sequential order". The
beginning of the file is then written first and the rest of the file stays a
sparse hole of the full final size.
4. While the download runs at a normal speed (tens of MB/s), open the download
folder in Dolphin.
5. Watch the process tree (Mission Center, System Monitor, or `ps -ef
--forest`). ffmpegthumbnailer processes appear under dolphin and keep
accumulating. CPU goes to 100% on all cores, the disk to 100% utilization, and
the desktop becomes unresponsive.
6. Leave the folder, switch the view mode, or close Dolphin. The
ffmpegthumbnailer processes do NOT go away. They keep running after Dolphin is
closed.
HOW IT WILL NOT REPRODUCE (why it "works for me")
- Downloading with Firefox, Chromium, or yt-dlp. They write into "*.part" and
rename at the end, so Dolphin never sees a growing video file. This is exactly
how 508839 was tested (comment 1: a .mov downloaded with Firefox), and the
reporter pointed it out in comment 2.
- Any client that writes incomplete data under a temporary name: qBittorrent
with "Append .!qB extension" enabled, or with "Keep incomplete torrents in" set
to a folder that is not open in Dolphin.
- Small or short-lived files: a short download or a fast local copy finishes
before the storm builds up. The file must keep being written for minutes.
- A folder that is not open in Dolphin while the file is written, previews
switched off, or a "skip previews above N MB" limit
(PreviewSettings/MaximumSize) lower than the file size.
- Only ffmpegthumbs installed, without the ffmpegthumbnailer package: the
endless regeneration (467774) still happens in thumbnail.so kioworkers, but the
pile-up of orphaned processes described in defect 2 below needs the
standard-thumbnailer path, i.e. a .thumbnailer file such as the one from
ffmpegthumbnailer.
What is needed: (a) a video that keeps its final name and extension while being
written, (b) a large file, ideally sparse from a torrent client in sequential
mode, (c) continuous writes with gaps longer than 100 ms, (d) the folder open
in Dolphin with previews on, for several minutes.
OBSERVED RESULT
- Dozens of ffmpegthumbnailer processes as children of the dolphin process, far
above the thumbnail worker limit.
- All CPU cores saturated; load average about 35 on an i7-4700HQ (4 cores / 8
threads).
- Disk saturated: each thumbnailer reads a 30-40 GB file that the torrent
client is writing at the same moment.
- Desktop frozen; applications starting at that time hit their timeouts;
Mission Center crashed with SIGABRT while I was killing the processes.
- Killing ffmpegthumbnailer by hand helps only until the next write to the
file, because Dolphin starts new ones.
- The processes survive leaving the folder and closing Dolphin.
EXPECTED RESULT
- A file that is still being written is not thumbnailed over and over: at most
one attempt, then nothing until the file has been unchanged for a reasonable
time.
- Cancelling a preview job (leaving the folder, view changes, closing Dolphin)
terminates the external thumbnailer process it started.
- There are never more thumbnailer processes than the configured worker limit.
ROOT CAUSE
Traced in the source of the releases I run: Dolphin v26.08.2 and KIO v6.30.0
(the relevant code is unchanged in current master). There are two independent
defects that multiply each other.
Defect 1 (Dolphin, regression since 20.08): a changed file is re-previewed
after only 100 ms of quiet
- Every write changes the file's mtime. KDirWatch reports it, and
slotItemsChanged() puts the item into m_recentlyChangedItems:
https://invent.kde.org/system/dolphin/-/blob/v26.08.2/src/kitemviews/kfileitemmodelrolesupdater.cpp#L491
- m_recentlyChangedItemsTimer is a single-shot timer with an interval of 100
ms, restarted on every change:
https://invent.kde.org/system/dolphin/-/blob/v26.08.2/src/kitemviews/kfileitemmodelrolesupdater.cpp#L110
After 100 ms without a change, resolveRecentlyChangedItems() ->
updateChangedItems() queues the item in m_pendingPreviewItems and starts a new
KIO::PreviewJob:
https://invent.kde.org/system/dolphin/-/blob/v26.08.2/src/kitemviews/kfileitemmodelrolesupdater.cpp#L810
https://invent.kde.org/system/dolphin/-/blob/v26.08.2/src/kitemviews/kfileitemmodelrolesupdater.cpp#L1109
https://invent.kde.org/system/dolphin/-/blob/v26.08.2/src/kitemviews/kfileitemmodelrolesupdater.cpp#L965
- A torrent client writes in bursts with gaps longer than 100 ms, so
practically every burst triggers a new preview for every file being written.
- In KIO, FilePreviewJob::isCacheValid() -> ThumbnailCache::matches() compares
Thumb::MTime and Thumb::Size with the file. Both change with every write, so
the cached thumbnail is never valid and a new thumbnailer process is started
every time:
https://invent.kde.org/frameworks/kio/-/blob/v6.30.0/src/gui/filepreviewjob.cpp#L335
This 100 ms is a regression:
- 2012, bug 295031: the Dolphin maintainer answered (comment 1) "Dolphin only
recreates the thumbnail if nothing has been downloaded for at least 2 seconds",
and the bug was closed as FIXED.
- 2013: commit 2bdc5eff541c set the interval to 1000 ms. Dolphin 18.08.0
through 20.04.3 have setInterval(1000).
https://invent.kde.org/system/dolphin/-/commit/2bdc5eff541c1e60fa197750e6aa73cee116beac
- 2020-05-04: commit e6ea3ab4c41d "[Details mode] Allow to fill the column size
of directories with actual size" changed it as a side change of the
directory-size feature:
- m_recentlyChangedItemsTimer->setInterval(1000);
+ m_recentlyChangedItemsTimer->setInterval(100);
https://invent.kde.org/system/dolphin/-/commit/e6ea3ab4c41dcc115143a237aafd3a1152849433
The same timer drives preview regeneration, so previews of files being
written are regenerated 10x more often than in 20.04, and 20x more often than
the 2 seconds promised in 295031.
- First release with 100 ms: Dolphin 20.08.0. The reports start right after:
431513 (January 2021), 457532 (2022), 467774 (2023), 508839 (2025).
Defect 2 (KIO): the external thumbnailer process is orphaned when the preview
job is cancelled
- StandardThumbnailJob::start() runs the .thumbnailer Exec line (for video:
"ffmpegthumbnailer -i %i -o %o -s %s -f") in a QProcess created without a
parent:
d->m_proc = new QProcess();
https://invent.kde.org/frameworks/kio/-/blob/v6.30.0/src/gui/standardthumbnailjob.cpp#L129
It is killed only in StandardThumbnailJob::doKill():
https://invent.kde.org/frameworks/kio/-/blob/v6.30.0/src/gui/standardthumbnailjob.cpp#L110
- FilePreviewJob stores the job as QPointer<StandardThumbnailJob>
m_standardThumbnailJob, created without a parent and never registered with
addSubjob():
https://invent.kde.org/frameworks/kio/-/blob/v6.30.0/src/gui/filepreviewjob.h#L174
https://invent.kde.org/frameworks/kio/-/blob/v6.30.0/src/gui/filepreviewjob.cpp#L547
- FilePreviewJob does not override doKill(), and ~FilePreviewJob() only removes
temporary files:
https://invent.kde.org/frameworks/kio/-/blob/v6.30.0/src/gui/filepreviewjob.cpp#L71
The only place that kills the external process is the 5-second timeout
started in start() and handled in slotTimeout():
https://invent.kde.org/frameworks/kio/-/blob/v6.30.0/src/gui/filepreviewjob.cpp#L131
https://invent.kde.org/frameworks/kio/-/blob/v6.30.0/src/gui/filepreviewjob.cpp#L740
- KIO::Job::doKill() kills only the registered subjobs(), and
StandardThumbnailJob is not one of them:
https://invent.kde.org/frameworks/kio/-/blob/v6.30.0/src/core/job.cpp#L164
- So whenever Dolphin cancels a preview job
(KFileItemModelRolesUpdater::killPreviewJob(): from updateChangedItems() when
the sort role is resolvable, slotItemsInserted(), slotItemsRemoved(),
slotSortRoleChanged(), startUpdating(), setPaused(), and from the destructor
when the view or Dolphin is closed), the FilePreviewJob is deleted together
with its 5-second timer, and the ffmpegthumbnailer process it started keeps
running with nobody left to kill it. When Dolphin exits, these processes are
reparented to init and keep running.
https://invent.kde.org/system/dolphin/-/blob/v26.08.2/src/kitemviews/kfileitemmodelrolesupdater.cpp#L1414
https://invent.kde.org/system/dolphin/-/blob/v26.08.2/src/kitemviews/kfileitemmodelrolesupdater.cpp#L1127
https://invent.kde.org/system/dolphin/-/blob/v26.08.2/src/kitemviews/kfileitemmodelrolesupdater.cpp#L140
- Combined with defect 1, which restarts previews after every write burst,
every cancellation leaves another orphan behind. That is how the count grows to
dozens, far above the thumbnail worker limit (maxInstances 5).
Why each process is so expensive in this case
A sequentially downloaded 40 GB .mkv is sparse: real data at the beginning, a
hole that reads as zeros after it. ffmpegthumbnailer seeks to 10% of the
duration by default. With sequential download that position usually has not
been downloaded yet, so the demuxer searches through a huge region without
valid data and then decodes 4K HEVC 10-bit in software. I did not trace
ffmpegthumbnailer itself, but this matches what I see: every process sits at
100% of a core, reads from a file that is being written at the same moment, and
runs for a long time. Multiplied by dozens of orphans, this is enough to freeze
the machine.
SUGGESTED FIXES
KIO (defect 2, needed regardless, it is a resource leak):
1. Override FilePreviewJob::doKill() to kill m_standardThumbnailJob and
m_transferjob before calling KIO::Job::doKill(), and do the same in
~FilePreviewJob().
2. Create the QProcess in StandardThumbnailJob with a parent and kill it in
~StandardThumbnailJob() if it is still running, or register
StandardThumbnailJob as a subjob of FilePreviewJob.
3. Optionally cap the number of concurrently running standard-thumbnailer
processes globally, not only per PreviewJob.
Dolphin (defect 1):
4. Do not drive preview regeneration with the 100 ms role-update debounce that
was introduced for the directory-size column. Give previews their own debounce
of at least 1-2 s, or better: do not regenerate the preview of an item whose
mtime keeps changing until it has been stable for several seconds (e.g. 5-10
s), then generate it once.
KIO / kio-extras (defence in depth, also covers file dialogs and Plasma folder
views):
5. Skip or defer thumbnail generation for files modified within the last few
seconds, and do not retry a file whose last attempt failed until its mtime has
been stable.
SOFTWARE/OS VERSIONS
Operating System: CachyOS (Arch-based), kernel 7.2.9-2-cachyos
KDE Plasma Version: 6.7.5
KDE Frameworks Version: 6.30.0
Qt Version: 6.12.0
Graphics Platform: Wayland
ADDITIONAL INFORMATION
Dolphin 26.08.2, kio-extras 26.08.2, ffmpegthumbs 26.08.2, ffmpegthumbnailer
2.3.1, FFmpeg 9.0.2
qBittorrent 5.2.4 (libtorrent-rasterbar 2.1.2), default settings plus "Download
in sequential order"
Hardware: Intel Core i7-4700HQ (4C/8T), 16 GB RAM, SATA SSD, btrfs on LUKS
--
You are receiving this mail because:
You are watching all bug changes.