Skip to content

idle.lock above ~24.8 days overflows the QTimer interval negative: ~400 warnings/sec exhausts shmem and crash-loops wayland-wm-app-daemon #9832

Description

@rnieuwen

What happened

A large idle.lock value in ~/.config/omarchy/shell.json overflows the idle service's QTimer interval, producing a runaway Qt warning loop that eventually exhausts shmem/tmpfs and takes the desktop down.

plugins/services/idle/Service.qml:267 binds the interval in milliseconds:

Timer {
  id: lockTimer
  interval: root.lockDelaySeconds * 1000
  repeat: false
  onTriggered: if (root.idleEnabled && root.idledThisCycle) root.lockSystem("lock-timeout")
}

QTimer/QQmlTimer intervals are a signed 32-bit int, so any lockDelaySeconds above 2147483 (~24.8 days) wraps negative. With idle.lock: 2592000 (30 days — a natural way to approximate "never lock"):

lockDelaySeconds = 2592000 - 150 = 2591850
2591850 * 1000   = 2591850000 ms
INT32_MAX        = 2147483647
wraps to         = -1702967296

Qt clamps the negative interval to 1ms and logs a warning on every timer start:

omarchy-shell[1194]: WARN: QBasicTimer::start: negative intervals aren't allowed; the interval will be set to 1ms.

Measured on my machine: ~424 warnings/second, 9,101,214 lines in a single session.

Impact

This is not just log noise. The flood escalates into a system-wide failure:

  1. Journald hits its 4G cap; weeks of real system history are rotated away.
  2. Quickshell's log memfd fills, and shmem/tmpfs allocation starts failing:
    omarchy-shell: ERROR quickshell.logging: Failed to copy log from memfd with error code 28 "No space left on device"
    voxtype:       WARN Failed to write PID file: No space left on device (os error 28)
    uwsm_app-daemon: [Errno 28] No space left on device
    
  3. wayland-wm-app-daemon.service crashes on the ENOSPC and enters a restart loop. Each restarted daemon receives a truncated request:
    uwsm_app-daemon: received:
    uwsm_app-daemon: sent: error 'Invalid arguments: ' 2
    
  4. Every app launch then fails with a critical App failure / Invalid arguments: desktop notification (urgency: 2, expireTimeout: 0, so they never expire and persist across restarts).

The machine became unusable and needed a hard restart. Note that df shows plenty of free disk throughout — the ENOSPC is shmem exhaustion, which makes this quite hard to diagnose from the symptom.

Steps to reproduce

  1. Set in ~/.config/omarchy/shell.json:
    "idle": { "screensaver": 150, "lock": 2592000 }
  2. Leave the machine idle for 150s so the idle cycle starts and lockTimer arms.
  3. Watch the flood:
    journalctl -f | grep QBasicTimer
    omarchy-shell idle status   # "lockDelay": 2591850, "timers": { "lock": true }

Expected

Either the timer is armed correctly for the configured duration, or the value is clamped/rejected — not silently wrapped into a 1ms busy loop.

Suggested fix

secondsFromConfig in plugins/services/idle/IdleModel.js already guards the low end but not the high end:

function secondsFromConfig(value, fallback) {
  var n = Number(value)
  if (!isFinite(n) || n < 0) return fallback
  return Math.floor(n)
}

Clamping to the largest value that survives the * 1000 conversion would fix it:

// Timer intervals are milliseconds in a signed 32-bit int.
var MAX_TIMER_SECONDS = 2147483  // floor(INT32_MAX / 1000)

function secondsFromConfig(value, fallback) {
  var n = Number(value)
  if (!isFinite(n) || n < 0) return fallback
  return Math.min(Math.floor(n), MAX_TIMER_SECONDS)
}

screensaverDelaySeconds (Service.qml:260) has the same exposure and would be covered by the same clamp.

Separately, it may be worth giving idle.lock an explicit "never" sentinel (e.g. 0 or false), since approximating it with a large number is what leads users into this.

System details

Omarchy 4.0.2-1
Kernel 7.1.9-arch1-2
CPU Intel Core i5-10400F
GPU NVIDIA GeForce GTX 1660 Ti (TU116)
quickshell 0.3.1-1
qt6-base 6.11.2-2

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions