如何追踪X11中无主窗口的创建进程及彻底解决方案


阅读 4 次

问题现象描述

最近在Ubuntu系统上遇到一个棘手的X窗口问题:一个始终置顶的透明窗口占据了屏幕部分区域,该窗口既无边框也无内容,但会拦截所有鼠标事件。通过xwininfo查询得到如下信息:

xwininfo: Window id: 0x1601b9f (has no name)
[...]
Override Redirect State: yes
Corners: +395+315 -383+315 -383-263 +395-263

快速应急处理

临时解决方案是使用xkill命令销毁窗口:

xkill -id 0x1601b9f

但这只是治标不治本,窗口可能会再次出现。

深度追踪技术

要彻底解决问题,需要找到创建窗口的进程。以下是几种有效方法:

方法1:使用xprop追踪

xprop -id 0x1601b9f _NET_WM_PID

如果窗口符合规范,会返回进程ID。但很多非常规窗口(如本案例)不会设置此属性。

方法2:结合xwininfo和lsof

# 首先获取窗口的XID
WIN_ID=$(xwininfo -root -children | grep "has no name" | awk '{print $1}')
# 然后查找关联文件描述符
lsof +E -a -p ^1 -c /./ -d 0-999 2>/dev/null | grep "x11"

方法3:使用xtrace工具

需要安装开发工具:

sudo apt-get install xtrace
xtrace -n 1000 | grep XCreateWindow

实战案例解析

最近处理的一个实际案例中,发现是某个Electron应用的插件导致的。通过以下脚本定位:

#!/bin/bash
# 监控X11窗口创建事件
xprop -spy -root _NET_CLIENT_LIST | while read -r line; do
  for win in ${line#*: }; do
    name=$(xprop -id $win WM_CLASS 2>/dev/null)
    if [[ "$name" == *"not found"* ]]; then
      echo "可疑窗口: $win"
      lsof -nP +E -a -c /./ -d 0-999 2>/dev/null | grep "x11.*$win"
    fi
  done
done

永久解决方案

针对反复出现的问题,建议:

  1. 检查~/.xsession-errors日志
  2. 逐个禁用开机启动项测试
  3. 使用strace跟踪可疑进程的X11调用

进阶工具推荐

对于开发者,可以考虑:

  • xscope - 实时监控X协议通信
  • x11trace - 低级别的X11调用跟踪
  • X11::Protocol - Perl模块用于深度分析