我在 ESX4.0 服务器上运行了一台 Debian VM。该 VM 托管多个用户,每个用户都在屏幕实例内运行一个 irssi 会话。
除了一个用户之外,它运行得很好。出于某种原因,这个 irssi 会话的 CPU 使用率一直达到 100%(同时继续正常工作)。它没有运行其他运行更正常的 irssi 会话中未加载的任何脚本。
CPU 100% 的情况不会立即出现,但通常在启动后几小时内就会出现。这种情况永远不会消失。
您将如何调试此问题的根源?我尝试使用 strace 进行调试,但没有立即发现任何明显的问题,尽管在启动时和达到峰值后的调用模式肯定有所不同。
开始时,这是 30 秒内的通话直方图:
time: 334
gettimeofday: 317
poll: 122
read: 9
write: 2
restart_syscall: 1
一旦 CPU 开始锁定,我就会得到以下信息:
gettimeofday: 230176
read: 115122
poll: 115106
time: 531
write: 107
waitpid: 38
_llseek: 2
ioctl: 2
fstat64: 2
open: 2
close: 2
fcntl64: 2
unlink: 1
挂钩过程的“ltrace -S”直方图显示这些是顶级条目:
SYS_read: 61731
g_io_channel_read: 34115
SYS_gettimeofday: 24662
SYS_poll: 12344
fflush: 6828
g_main_context_iteration: 6823
__ctype_toupper_loc: 4025
g_strcasecmp: 3757
g_hash_table_lookup_extended: 3325
g_direct_hash: 3068
我遗漏了什么?下一步该怎么做才能解决这个问题?
答案1
我认为您需要弄清楚它为什么如此频繁地读取和轮询。由于它不是经常打开和关闭新文件(显然每 30 秒只有两个),lsof 应该会告诉您这一点。
如果它是从管道读取(),如下所示:
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
irssi 4993 user 5w FIFO 0,6 2941908 pipe
然后以 root 身份针对所有进程运行 lsof,并在其输出中 grep 管道,可以是命名管道的名称,也可以是未命名管道的节点号。(在本例中为 2941908。)这将向您显示 irssi 以及管道另一端的任何进程。
如果管道没有另一端……呃,我不确定。也许可以对其中一个进程进行 strace,从开始到问题发生,然后找出管道出了什么问题。使用 '-e trace=' 标志限制 strace 的输出可能有意义,但我暂时想不出一套好的限制方法。