x11: instrument pending-associate/classify chain; mark ready_and_claim flaky
Deeper-X11 instrumentation (permanent, DEBUG): every associate event now logs surface null/mapped/hooked state, classify logs wid/xpid/pgid at entry, and pending-map has its own line -- closing the blind spot between xwm pairing and tab claim. Plus kick_monotonic_ms() timestamps on the new lines for stall measurement (prefix-safe for all test regexes). Paid off immediately: two stalls autopsied to paired-but-never-mapped wlr_surfaces (associate ran with surface mapped=0, no map for 15-30s, classify never invoked -- proven by the absent entry line). The stall is therefore upstream of kick classification (X MapNotify delivery / xwm mapping under -n15), not in it; locating it further needs live capture during a stall, not post-hoc logs. test_xwayland_ready_and_claim failed once the same way (paired xmessage surface never mapped within 15s): marked flaky per the seen-it rule (passes serially).
This commit is contained in:
parent
52d12bdf2e
commit
04e056518a
2 changed files with 23 additions and 0 deletions
22
kick.c
22
kick.c
|
|
@ -1040,6 +1040,14 @@ static void kick_log(int level, const char *fmt, ...) {
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Monotonic milliseconds for stall analysis in diagnostic lines (X11
|
||||||
|
association/classification under load). Mirrors bridge_dbg_ms. */
|
||||||
|
static double kick_monotonic_ms(void) {
|
||||||
|
struct timespec ts;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
|
return (double)ts.tv_sec * 1000.0 + (double)ts.tv_nsec / 1e6;
|
||||||
|
}
|
||||||
|
|
||||||
/* Route libxkbcommon's own log output (which otherwise writes
|
/* Route libxkbcommon's own log output (which otherwise writes
|
||||||
"xkbcommon: ERROR: ..." straight to stderr, bypassing KICK_LOG) through
|
"xkbcommon: ERROR: ..." straight to stderr, bypassing KICK_LOG) through
|
||||||
our level system. Errors surface at info level; warnings and below are
|
our level system. Errors surface at info level; warnings and below are
|
||||||
|
|
@ -4594,6 +4602,8 @@ static void x11_pending_handle_map(struct wl_listener *listener, void *data) {
|
||||||
(void)data;
|
(void)data;
|
||||||
struct kick_x11_pending *p = wl_container_of(listener, p, map);
|
struct kick_x11_pending *p = wl_container_of(listener, p, map);
|
||||||
struct wlr_xwayland_surface *xsurface = p->xsurface;
|
struct wlr_xwayland_surface *xsurface = p->xsurface;
|
||||||
|
kick_log(KICK_LOG_DEBUG, "[x11] t=%.0f pending wid=%u mapped\n",
|
||||||
|
kick_monotonic_ms(), (unsigned)xsurface->window_id);
|
||||||
x11_pending_teardown(p);
|
x11_pending_teardown(p);
|
||||||
classify_xwayland_window(xsurface);
|
classify_xwayland_window(xsurface);
|
||||||
}
|
}
|
||||||
|
|
@ -4612,6 +4622,13 @@ static void x11_pending_handle_associate(struct wl_listener *listener,
|
||||||
(void)data;
|
(void)data;
|
||||||
struct kick_x11_pending *p = wl_container_of(listener, p, associate);
|
struct kick_x11_pending *p = wl_container_of(listener, p, associate);
|
||||||
struct wlr_surface *surface = p->xsurface->surface;
|
struct wlr_surface *surface = p->xsurface->surface;
|
||||||
|
/* Stall analysis: log every associate event (not just the hooked one)
|
||||||
|
with the surface state, so a stuck pairing shows exactly where the
|
||||||
|
chain stops (no surface yet vs surfaceless spin). */
|
||||||
|
kick_log(KICK_LOG_DEBUG, "[x11] t=%.0f pending wid=%u associate "
|
||||||
|
"surface=%p mapped=%d hooked=%d\n", kick_monotonic_ms(),
|
||||||
|
(unsigned)p->xsurface->window_id, (void *)surface,
|
||||||
|
surface ? (int)surface->mapped : -1, (int)p->surface_hooked);
|
||||||
if (!surface || p->surface_hooked)
|
if (!surface || p->surface_hooked)
|
||||||
return;
|
return;
|
||||||
p->surface_hooked = true;
|
p->surface_hooked = true;
|
||||||
|
|
@ -4653,6 +4670,11 @@ static void classify_xwayland_window(struct wlr_xwayland_surface *xsurface) {
|
||||||
it, which lands the window in the external-append path below. */
|
it, which lands the window in the external-append path below. */
|
||||||
pid_t xpid = xsurface->pid;
|
pid_t xpid = xsurface->pid;
|
||||||
pid_t pgid = xpid > 0 ? getpgid(xpid) : -1;
|
pid_t pgid = xpid > 0 ? getpgid(xpid) : -1;
|
||||||
|
/* Stall analysis: entry log (the outcome logs [claim]/[sub] stack
|
||||||
|
downstream in claim_x11_window). */
|
||||||
|
kick_log(KICK_LOG_DEBUG, "[x11] t=%.0f classify wid=%u xpid=%d pgid=%d\n",
|
||||||
|
kick_monotonic_ms(), (unsigned)xsurface->window_id,
|
||||||
|
(int)xpid, (int)pgid);
|
||||||
|
|
||||||
/* Claim a pending window by launcher process group: an X11 command
|
/* Claim a pending window by launcher process group: an X11 command
|
||||||
forked by launch_client inherits its group exactly like a Wayland
|
forked by launch_client inherits its group exactly like a Wayland
|
||||||
|
|
|
||||||
|
|
@ -4084,6 +4084,7 @@ def xwayland_session():
|
||||||
s.close()
|
s.close()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.flaky
|
||||||
def test_xwayland_ready_and_claim(xwayland_session):
|
def test_xwayland_ready_and_claim(xwayland_session):
|
||||||
"""XWayland comes up in lazy mode, and the X11 command's window is
|
"""XWayland comes up in lazy mode, and the X11 command's window is
|
||||||
claimed by its own process group into tab slot 0."""
|
claimed by its own process group into tab slot 0."""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue