A stall catcher on the browser must pick the WebKitWebProcess with the most threads, and thread names are truncated from the front
scope: generic · severity: trap · confidence: proven · subsystem: browser
Symptom – a process- or thread-level instrument on the browser (a stall
catcher, threadcpu.py, eu-stack -p, a per-thread sampler) runs for the
whole window and reports a clean null: 0 captures, an idle main thread, no
GStreamer threads, or no thread matching 'ThreadedCompo'. Meanwhile the
frame log shows two-second holes. The null reads as “the web process is not
the problem”.
Cause – two independent things, either enough for the null:
- Epiphany runs SEVERAL
WebKitWebProcess(one per site isolation group plus prewarmed and idle ones – five with a single YouTube tab). A scan of/procthat takes the first match bycommgets an idle one. The page with the media pipeline is the one with by far the most threads (73 vs 14-27 here). - Linux keeps 15 characters of a thread name, and WTF’s thread names are
truncated from the FRONT:
ThreadedCompositoriseadedCompositor,InterruptDispatcherisrruptDispatcher. A prefix match on the WebKit name finds nothing; a substring match (Compositor) does.
What to do – choose the target WebKitWebProcess by thread count
(max(len(os.listdir(f"/proc/{pid}/task")))), and match thread names by
substring against the last 15 characters. tools/ph-stallcatch.py does both;
threadcpu.py matches by cmdline substring and is safe. Before believing any
null from such an instrument, print which pid and which tid it attached to –
the run that finally caught the blur printed pid=59014 tid=59043 (eadedCompositor) threads=52 first.
Related: uprobes-do-not-attach-to-an-already-mapped-library,
youtube-video-freezes-are-a-software-css-blur-on-the-main-thread.
