当登录到我的 Ubuntu 12.04 工作站时,执行一些相对无害的操作,例如在终端中按制表符自动完成、切换工作区、移动窗口等,可能会导致 Metacity 冻结 30 秒。
按照步骤这里为了诊断问题,我首先将冻结前和冻结期间的状态进行比较ps axo pid,wchan:32,cmd > [not-]frozen.txt
,然后diff
发现:
$ diff frozen.txt not_frozen.txt
142c142
< 7135 futex_wait_queue_me metacity
---
> 7135 poll_schedule_timeout metacity
通过对 Metacity 进行更深入的跟踪,可以发现它与那个“futex”绑定了整整 30 秒((sudo strace -p 11773 3>&1 1>&2- 2>&3-) | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; fflush(); }' > metacity-trace.txt
):
2014-07-03 15:49:50 clone(child_stack=0xac1982a4, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xac198ba8, {entry_number:6, base_addr:0xac198b40, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0,useable:1}, child_tidptr=0xac198ba8) = 8659
2014-07-03 15:49:50 futex(0x9a55228, FUTEX_UNLOCK_PI_PRIVATE, 161978120) = 0
2014-07-03 15:49:50 futex(0x9a7970c, FUTEX_WAIT_REQUEUE_PI_PRIVATE, 1, NULL, 0x9a55228) = 0
2014-07-03 15:49:50 futex(0x9a55228, FUTEX_UNLOCK_PI_PRIVATE, 161978120) = 0
2014-07-03 15:50:20 futex(0x9a7970c, FUTEX_WAIT_REQUEUE_PI_PRIVATE, 3, NULL, 0x9a55228) = 0
2014-07-03 15:50:20 futex(0x9a55228, FUTEX_UNLOCK_PI_PRIVATE, 122875892) = 0
2014-07-03 15:50:20 send(15, "W", 1, MSG_NOSIGNAL) = -1 ENOTSOCK (Socket operation on non-socket)
那是在 Unity 2D 下,如果我使用 Gnome Classic,尝试切换桌面时也会发生同样的事情(但它对终端中的自动完成不那么敏感)。
2014-07-03 16:07:31 clone(child_stack=0xb21fe2a4, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xb21feba8, {entry_number:6, base_addr:0xb21feb40, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}, child_tidptr=0xb21feba8) = 12693
2014-07-03 16:07:31 futex(0x98424e8, FUTEX_UNLOCK_PI_PRIVATE, 160065584) = 0
2014-07-03 16:07:31 futex(0x98a6834, FUTEX_WAIT_REQUEUE_PI_PRIVATE, 1, NULL, 0x98424e8) = -1 EAGAIN (Resource temporarily unavailable)
2014-07-03 16:07:31 futex(0x98424e8, FUTEX_UNLOCK_PI_PRIVATE, 160065584) = 0
2014-07-03 16:08:01 futex(0x98a6834, FUTEX_WAIT_REQUEUE_PI_PRIVATE, 3, NULL, 0x98424e8) = 0
2014-07-03 16:08:01 futex(0x98424e8, FUTEX_UNLOCK_PI_PRIVATE, 13762548) = 0
2014-07-03 16:08:01 send(14, "W", 1, MSG_NOSIGNAL) = -1 ENOTSOCK (Socket operation on non-socket)