linux - 如何更好地诊断哪个客户端导致高 Xorg CPU 使用率?
问题描述
我遇到了Xorg 服务器突然变得非常慢并且它的 CPU 使用率达到 100%的问题。谷歌搜索表明这个问题的“最先进”调试方法是开始随机杀死 X 客户端,直到问题消失,然后你知道哪个客户端是有问题的客户端(祝你好运在杀死它后尝试调试进程) . 没有一个 X 客户端正在消耗大量 CPU(每个最多大约 1% 的 CPU)。并且系统仍然有 2GB 的可用 RAM。
有人知道更好地诊断问题的方法吗?基本上,我正在寻找top
Xorg 的替代品,它会直接将我指向导致 Xorg 使用最多 CPU 的客户端进程。我已经知道xrestop
Xorg 内存使用情况是一样的,但这个问题专门针对 CPU 使用情况。
造成这种减速的另一个原因可能是 GPU 内存不足,这可能会导致通过 PCI-express 总线推送位图,而不是直接从 GPU 内存渲染到显示。如果这显示为内核级别的 CPU 使用率(例如top
),这可能是我看到的问题,但我想更好地了解原因。当我从有问题的系统中写这篇文章时,似乎大多数减速都发生在输入处理或字体渲染中,但我不知道如何更好地诊断这件事。
我知道可以使用另一台计算机连接ssh
,将gdb
进程附加到有问题的 Xorg 服务器并开始挖掘,但我希望能更容易一些。
如果我得到问题客户端的 PID 甚至窗口句柄,找出根本原因会更容易(例如https://unix.stackexchange.com/q/5478)。而且我不需要杀死行为良好的进程作为副作用。
解决方案
这是一个脚本,用于确定是否是某个客户端导致了问题(但对我的问题没有帮助):
#!/bin/bash
WINDOW_IDS=$(xwininfo -tree -root | grep -o -P '\b0x[0-9a-f]+' | sort -u)
PIDS=""
for ID in $WINDOW_IDS
do
if [ "$ID" = "0x0" ]
then
continue
fi
#printf "Window %s PID=" "$ID"
PID=$(LC_ALL=C xprop -id "$ID" _NET_WM_PID | cut -d' ' -f3-)
if [ "$PID" = "not found." ]
then
# printf "%s\n" "(unknown)"
# See also: https://unix.stackexchange.com/a/84981
true
else
# printf "%s\n" "$PID"
PIDS="$PIDS $PID"
fi
done
PIDS=$(printf "%s\n" $PIDS | sort -u)
# go through the list of processes connected to Xorg:
for PID in $PIDS
do
printf "%s: %s\n" "$PID" "$(cat /proc/$PID/cmdline)"
sleep 0.1s # wait for the previous line to get on the screen before stopping e.g. compositing manager
# Stop the process for 5 secs and let the process continue after that.
kill -STOP "$PID" && sleep 1s && kill -CONT "$PID"
done
这个想法是依次停止每个客户端 5 秒,如果这可以解决问题 5 秒,那么您就发现了问题。该脚本发送SIGSTOP
到不能被忽略的目标进程,并阻止目标进程获取 CPU 时间,因此它也无法向 Xorg 发送任何事件。请注意,如果您在中间终止此脚本,您最终可能会导致其中一个进程处于 STOPPED 状态。发送SIGCONT
以解决问题。如果您等待脚本完成,一切都应该没问题。(另见:https ://unix.stackexchange.com/a/298650 )
就我而言,无论哪个客户端停止,Xorg 都会一直运行缓慢,所以我想我看到的问题是内部 Xorg 问题,我需要使用 FlameGraphs(http://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html ) 找出问题的真正原因。
推荐阅读
- java - 尝试使用 FireBase 登录后,应用重定向到注册页面
- css - 溢出换行:任何地方和溢出换行:断字之间的区别?
- python - 创建多个图:作为索引器提供的不可对齐的布尔系列
- vb.net - 如何使用户出错的抽认卡更频繁地出现 - visual basic
- python - Discord.py 中的频道 ID 比较
- c# - 生成二进制文件以在 Linux 中执行 C# Visual Studio 脚本
- asp.net-core - 尝试在 OWIN Web API Windows 服务 (.NET 5.0) 中实现 DI
- vue.js - 如何为生产服务器转换完美的 devServer 配置文件。因为本地没有错误,并且在部署 cors 错误之后
- android - 如何从firebase获取基于时间戳的排序数据
- spring-boot - 单独捕获所有请求和响应