protonscr

steamwebhelper crashes with SIGSEGV in libcef.so, main window never opens (native and Flatpak)

steamopen Distro Family: UbuntuWeb Component
ValveSoftware/steam-for-linux#13483 · opened 2026-08-05 by adrisgg00 · updated 2026-10-24 · 4 comments · github
Aadrisgg00 2026-08-05 github

Steam client won't stay open. The tray icon runs fine (I can use it to quit Steam), but the main library/store window never opens or stays open. steamwebhelper crashes and restarts in a loop, confirmed via cef_log.txt showing startcount incrementing every ~10 seconds. Big Picture mode also crashes immediately.

Confirmed via coredumpctl: steamwebhelper crashes with SIGSEGV, with the crash occurring inside libcef.so specifically (the same crash address is repeated across the entire stack trace, suggesting a stack overflow/infinite recursion inside CEF).

This happens identically across two completely separate install methods:

  1. Native Steam (.deb via apt)
  2. Fresh Flatpak install of com.valvesoftware.Steam

Both show the same SIGSEGV crash in libcef.so.

Things already tried, none of which fixed it:

  • Reinstalled all Steam packages and dependencies
  • Launched with --no-sandbox
  • Forced software rendering (LIBGL_ALWAYS_SOFTWARE=1) and disabled GPU compositing (--disable-gpu --disable-gpu-compositing)
  • Tried multiple desktop themes (Mint-Y, Adwaita, Mint L)
  • Tried GLIBC_TUNABLES=glibc.rtld.optional_static_tls=4096
  • Full clean reinstall (wiped ~/.steam and ~/.local/share/Steam)
  • Checked AppArmor (aa-status), nothing blocking
  • Confirmed plenty of free disk space

System info:

  • Linux Mint 22.3, Cinnamon desktop
  • Kernel: 7.0.0-28-generic
  • CPU: Intel Core i3-12100F
  • GPU: AMD Radeon RX 5700 XT (RADV NAVI10, Mesa 25.2.8)
  • RAM: 16GB
  • Steam build ID: 1785799196

Since this crashes identically on two separate install methods with different bundled libraries, this seems like a real bug rather than a local config issue. Happy to provide any additional logs or test any suggested fixes.

AABrony 2026-10-04 github

I thought it may be useful to add: it does also happen on Arch distro. So there's chance it's not distro-dependent. Although in may case it just restarts after crash like nothing happened and then works extremely stable. So it may be a slightly different problem. Here's small part of a log that i thought was somewhat relevant, including crash dump. (it was pretty much only thing that caught my eye)

steamwebhelper_dump.txt

In general Steam is acting weird lately, can even cause CPU soft lockup sometimes, but that's completely different topic.

KKokoteAdvice 2026-10-24 github
Same crash on native Steam here, and I can contribute a cause plus a deterministic trigger.

Environment: Arch (rolling) + Hyprland, Steam runs as an X11 client under XWayland. NVIDIA RTX 5070 Ti, proprietary 615.78.08. Native install (not Flatpak). Client 1792618285, and publicbeta 1792711043. Mouse: 8 kHz polling (USB bInterval=1).

Signature (identical in every core — 50 of them)

One function calls itself until the thread stack is exhausted. coredumpctl truncates the trace; measuring the faulting thread's stack in an extracted core gives:

measurement value
repeated frames of the same return address 18 664
bytes per frame 448
stack consumed by the recursion 0x7f9440 = 7 MiB (8 MiB thread stack)
#1  libcef.so + 0x67cae43      <- innermost libcef frame: the function that calls realpath()
#2  libcef.so + 0x7cab84a
#3..#N  libcef.so + 0x7cabe3b  <- repeated 18 664 times

Recursive function start libcef.so+0x7cab460, recursive call site libcef.so+0x7cabe3b. Disassembly of the call site is a walk over a container of 24-byte elements that calls the same function per element until one returns non-null:

7cabe20:  cmp  %r14,%rbx          ; end of container
7cabe23:  je   7cabe55
7cabe2c:  mov  -0xc8(%rbp),%rsi   ; context
7cabe33:  mov  %rbx,%rdi
7cabe36:  call 7cab460            ; <- recursion, return address 0x7cabe3b
7cabe3b:  test %rax,%rax
7cabe3e:  jne  7cabe55
7cabe40:  add  $0x18,%rbx         ; sizeof(element) == 24
7cabe4e:  jne  7cabe33

Deepest recovered frames sit in the message-loop / thread-bootstrap range (0x67b7210, 0x67b72a3, 0x679e264, 0x67a59bc, 0x675b2ec). The faulting thread is a CEF ThreadPoolForeg worker (TID 107786), not the browser thread; I'm not claiming to know which handler chain recurses, only that the recursion and its depth are exactly reproducible:

Stack trace of thread 107786:   (coredumpctl -1 info steamwebhelper)
#0  /run/host/usr/lib/libc.so.6 + 0x3fea0     -> realpath (addr2line; .dynsym nearest preceding realpath@@GLIBC_2.3 @0x3fe60)
#1  libcef.so + 0x67cae43
#2  libcef.so + 0x7cab84a
#3..[#18666](/issue/ValveSoftware/steam-for-linux/18666)  libcef.so + 0x7cabe3b
Signal: 11 (SEGV) si_code: SEGV_MAPERR

Frame #0 being inside glibc's realpath, with SEGV_MAPERR, is consistent with that call trying to extend a stack that the recursion has already filled — i.e. the recursion bottomed out in a path-resolution call.

Trigger: the count of X11 MotionNotify events, not their rate

Reproduced with XTEST-injected motion, so it bypasses evdev, the kernel input layer and any pointer-acceleration driver — no real device is involved. Steam window focused, coordinates inside it:

injected motion events result
0 (idle 90 s) stable, helper PID unchanged
625 events @ 125 Hz no crash
48 000 events @ 8 kHz (6 s) SIGSEGV, offsets above
240 000 events @ 8 kHz (30 s, beta) 2 crash-restarts
60 000 events @ 1 kHz (60 s, beta) 7 crash-restarts

~18.6k events is the budget, at any delivery rate. The 1 kHz row is why the crash becomes a loop rather than a one-off: after the watchdog respawns the helper, the events already queued in the X socket hit it in one burst and it dies again within seconds — which matches the -startcount= incrementing every ~10 s.

#!/usr/bin/env python3
# flood.py <rate_hz> <seconds> <x0> <y0> <x1> <y1>   (needs python3-xlib)
import sys, time
from Xlib import X, display
from Xlib.ext import xtest

hz, secs = float(sys.argv[1]), float(sys.argv[2])
x0, y0, x1, y1 = map(int, sys.argv[3:7])
d = display.Display(':1')
n, batch, sent, i = int(hz*secs), max(1, int(hz/500)), 0, 0
t0 = time.time()
while sent < n:
    for _ in range(batch):
        xtest.fake_input(d, X.MotionNotify, x=x0+((i*37)%(x1-x0)), y=y0+((i*53)%(y1-y0)))
        i += 1; sent += 1
    d.sync()
    t = t0 + sent/hz
    if t > time.time(): time.sleep(t-time.time())
d.sync()

Regression correlation (same libcef.so, opposite crash rate)

  • Client 1791918634 (Oct 21 → Oct 24): 1 steamwebhelper core in 3 days, with this same 8 kHz mouse attached the whole time.
  • Steam auto-updated to 1792618285 at 12:42; first SIGSEGV 12:43:22; 19 more in 12 minutes.

So the engine binary did not change between those two builds — the client's event dispatch around it did.

Why the beta cannot help

libcef.so is byte-identical on release 1792618285 and publicbeta 1792711043: 219 444 168 bytes, mtime Aug 15, md5 b001c1ca15dcad948b7081cd8bd01d1d. Same recursion offsets in beta cores.

Already ruled out on this machine

GPU compositing on and off for web views (GPUAccelWebViewsV3=0 → helper really does get --disable-gpu --disable-gpu-compositing, vs =1 with GPU compositing active) — identical either way; X cursor theme; a kernel pointer-acceleration module (the XTEST repro never touches kernel input); second, rotated monitor; -cef-disable-gpu; verification / reinstall (Steam restores ubuntu12_64/steamwebhelper_sniper_wrap.sh on launch, so wrapper-level flag edits don't survive).

The core itself is 13.7 MB (/var/lib/systemd/coredump/core.steamwebhelper.1000.97485d4d151b404c9dcb914435a6ec89.107773.1792844064000000.zst) — over GitHub's issue-attachment size limit, so it is not attached; say the word and I'll put it somewhere you can pull it from.

Is a bundled Chromium/CEF refresh pending that addresses re-entrant X11 event dispatch, or is a stack guard / motion-event cap something that can be turned on client-side?

KKokoteAdvice 2026-10-24 github
Follow-up with two controlled comparisons on the same build (publicbeta `1792711043`, `libcef.so` md5 `b001c1ca15dcad948b7081cd8bd01d1d`), X11 via Xwayland under Hyprland.

Motion is injected with XTEST at a fixed rate — 8 kHz x 30 s = 240 000 MotionNotify events — and only the hovered content varies:

pointer region SIGSEGV count
library hero / "What's New" animated tiles 3
collection sidebar (static game list) 0
idle, cursor off the window 0

Identical event count and rate, different pixel: 3 vs 0. So this is not an event-count budget. My earlier comment's 18 664 identical frames x 448 B = 7 MiB of an 8 MiB thread stack is the recursion depth at the crash, not a quota of events that gets spent.

Also tested: raising the process stack limit does not help. With Max stack size 67108864 in steamwebhelper's limits, the same 240 000 events gave 3 crashes with the same trace (realpath in libc at the innermost frame, libcef+0x67cae43 then repeated libcef+0x7cabe3b). The recursion looks unbounded, so the depth comes from whatever is being hit-tested rather than from a chain that grows over the process lifetime.

For the same reason, throttling the rate reaching the helper does not prevent it either: a compositor-side motion cap (~250 Hz while Steam is focused, all other clients untouched) still gave 5 SIGSEGVs in about 2 minutes of ordinary library browsing.

Llourencovales 2026-10-24 github

I don't have much to add, just another corroboration: Arch + Hyprland, steam client stable and beta. steamwebhelper dumps core in a loop, ~2-3s apart. coredumpctl reports Signal: 11 (SEGV) si_code: SEGV_MAPERR, with the entire stack inside libcef.so and the same offsets (+0x673f6be, +0x677f721, +0x6714ee7) recurring across threads.

Nothing extracted yet.