linebender/druid · critical

error allocating shared memory

Error message

error allocating shared memory

What it means

Panic raised by an `.expect()` when creating a `Shm` wrapper over the wayland `wl_shm` global fails during `Surface::new`. Wayland shared-memory (shm) allocation is how the shell gets pixel buffers to the compositor; if the protocol object cannot be created or its initial round-trip fails, there is no fallback path, so the library deliberately aborts surface construction.

Solutions

  1. Verify the compositor exposes wl_shm (e.g. `wayland-info`); switch to a standard compositor (Mutter, KWin, wlroots-based) if not
  2. Check WAYLAND_DISPLAY / WAYLAND_SOCKET / XDG_RUNTIME_DIR environment variables point at a live, writable socket
  3. Ensure the app is not running in a sandbox that blocks wayland globals; adjust sandbox permissions or fall back to X11 backend
  4. Update wayland-rs / smithay-client-toolkit dependencies and the compositor to compatible versions

Example fix

// before (library code, unavoidable)
let shm = Shm::new(wl_shm).expect("error allocating shared memory");
// after (caller-side guard: don't build surfaces on compositors lacking wl_shm)
let globals = GlobalsState::new_from_thread(&conn).unwrap();
assert!(globals.contents().bind_list().iter().any(|g| g.interface == wl_shm::WlShm::name()), "compositor lacks wl_shm");
Defensive patterns

Strategy: validation

Validate before calling

// Before creating wayland surfaces, confirm wl_shm is bound
// (using wayland-client's globals)
let has_shm = globals
    .contents()
    .bind_list()
    .iter()
    .any(|g| g.interface == wl_shm::WlShm::name());
if !has_shm {
    eprintln!("compositor does not support wl_shm; cannot render");
    std::process::exit(1);
}

Try / catch

// Rust panics here, not Results; recover at process level:
let result = std::panic::catch_unwind(|| run_app());
if result.is_err() {
    eprintln!("failed to init wayland shm; falling back to X11 backend");
}

Prevention

When it happens

Trigger: Calling surface/window creation APIs (e.g. `Surface::new` in the wayland backend) on a compositor that does not expose a working `wl_shm` global, a broken/stale wayland connection, or a compositor that rejects the shm protocol object during initialization.

Common situations: Running under a compositor or remote-display setup without wl_shm support (e.g. some nested/special-purpose compositors), connecting over a broken WAYLAND_SOCKET/WAYLAND_DISPLAY environment, sandboxed environments (flatpak/containers) that filter wayland globals, or version mismatches between the client library and compositor.

Related errors


AI-assisted analysis of linebender/druid@0f8b1195e4 (2026-09-10). Data as JSON: /api/errors/35244578db9b7d64. Report an issue: GitHub.

Appendix: source

Thrown at druid-shell/src/backend/wayland/surfaces/buffers.rs:79

    pending_buffer_borrowed: Cell<bool>,

    /// Shared memory to allocate buffers in
    shm: RefCell<Shm>,
}

impl<const N: usize> Buffers<N> {
    /// Create a new `Buffers` object.
    ///
    pub fn new(wl_shm: wl::Main<WlShm>, size: RawSize) -> Rc<Self> {
        assert!(N >= 2, "must be at least 2 buffers");
        Rc::new(Self {
            released: Cell::new(Vec::new()),
            buffers: Cell::new(None),
            pending: Cell::new(0),
            size: Cell::new(size),
            recreate_buffers: Cell::new(true),
            pending_buffer_borrowed: Cell::new(false),
            shm: RefCell::new(Shm::new(wl_shm).expect("error allocating shared memory")),
        })
    }

    /// Get the physical size of the buffer.
    pub fn size(&self) -> RawSize {
        self.size.get()
    }

    /// Request that the size of the buffer is changed.
    pub fn set_size(&self, updated: RawSize) {
        assert!(!updated.is_empty(), "window size must not be empty");
        let old = self.size.replace(updated);
        self.recreate_buffers.set(old != updated);
    }

    /// Request painting the next frame.
    ///
    /// This calls into user code. To avoid re-entrancy, ensure that we are not already in user

View on GitHub (pinned to 0f8b1195e4)