AJM*_*eld 5 process kill ps process-management
任何时候我尝试运行ps使其输出任何进程的参数的方式运行该命令或另一个类似命令时,该命令都会运行并生成输出,但随后会冻结,进入永远不会退出的“不间断睡眠”状态。
目前,我有 17 个冻结进程仍然坐在那里(摘自top -u $USER):
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND\n 8807 foo_user 20 0 28912 2984 2680 D 0.0 0.0 0:00.10 ps\n14040 foo_user 20 0 29124 3108 2796 D 0.0 0.0 0:00.14 ps\n14342 foo_user 20 0 28912 2972 2668 D 0.0 0.0 0:00.10 ps\n15528 foo_user 20 0 28912 3028 2724 D 0.0 0.0 0:00.10 ps\n16677 foo_user 20 0 28912 2992 2692 D 0.0 0.0 0:00.11 ps\n18723 foo_user 20 0 28912 3000 2696 D 0.0 0.0 0:00.12 ps\n19427 foo_user 20 0 29124 3080 2772 D 0.0 0.0 0:00.14 ps\n19587 foo_user 20 0 29124 3108 2804 D 0.0 0.0 0:00.08 ps\n19917 foo_user 20 0 29124 3056 2748 D 0.0 0.0 0:00.08 ps\n20267 foo_user 20 0 29124 3056 2760 D 0.0 0.0 0:00.10 ps\n20566 foo_user 20 0 29124 1604 1412 D 0.0 0.0 0:00.09 ps\n21189 foo_user 20 0 28912 2940 2648 D 0.0 0.0 0:00.10 ps\n21296 foo_user 20 0 28912 1524 1332 D 0.0 0.0 0:00.10 ps\n21674 foo_user 20 0 28840 3208 2648 D 0.0 0.0 0:00.07 pgrep\n26220 foo_user 20 0 28912 2968 2672 D 0.0 0.0 0:00.10 ps\nRun Code Online (Sandbox Code Playgroud)\n除了 之外pgrep,所有这些最初都是从 bash shell 在 ssh 会话中启动的;此后,我手动终止了sshd和bash进程,但子ps进程仍然存在。pid 21674 是我按下内部尝试以 \xe2\x80\x94 方式列出命令行参数的pgrep结果,导致在等待时也冻结ctoptoppgrep输出时也冻结。
我已经排除了某些正在运行的进程的参数在某种程度上“脏”(太长?包含控制字符?)并导致这种情况的可能性,因为即使在尝试显示我知道的一个特定 PID 的参数时也会发生冻结是安全且正常的,例如:
\nfoo_user@my_machine:~$ ps 14040\n PID TTY STAT TIME COMMAND\n14040 ? D 0:00 ps -aux\nRun Code Online (Sandbox Code Playgroud)\n(它也以完全相同的方式冻结,现在 pid 22620 在上面的列表中。)
\n但是,使用ps未列出完整进程命令行的参数运行不会导致此冻结。我能够成功运行ps -u $USERor top -u $USER,获取输出,并使这些进程正常退出。
冻结的进程不会响应任何标准输入,包括通常会退出或挂起正在运行的进程的控制字符,如ctrlC或。ctrlZ他们也不响应任何信号;即使发送 SIGKILL (通过kill -9)也不会使这些进程退出。
请注意,这是一个多用户系统,我没有超级用户访问权限。
\n为什么这些进程会像这样冻结,以及如何在不冻结列表进程的情况下列出进程的参数?
\n我运行了@StephenKitt 建议的一些命令。
\n第一个命令简单地给出了一个错误:
\nfoo_user@my_machine:~$ strace -p 8807\nstrace: attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted\nCould not attach to process. If your uid matches the uid of the target\nprocess, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try\nagain as the root user. For more details, see /etc/sysctl.d/10-ptrace.conf\nRun Code Online (Sandbox Code Playgroud)\n第二个命令显示,由于某种原因, ps 命令仍然打开并读取每一个/proc/*/cmdline,而不仅仅是指定的一个。
foo_user@my_machine:~$ strace ps 14040\n\xe2\x8b\xae\n\xe2\x8b\xae\nstat("/proc/30825", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0\nopen("/proc/30825/stat", O_RDONLY) = 6\nread(6, "30825 (gvfsd-network) S 1 2650 2"..., 2048) = 186\nclose(6) = 0\nopen("/proc/30825/status", O_RDONLY) = 6\nread(6, "Name:\\tgvfsd-network\\nState:\\tS (sl"..., 2048) = 1000\nclose(6) = 0\nopen("/proc/30825/cmdline", O_RDONLY) = 6\nread(6, "/usr/lib/gvfs/gvfsd-network\\0--sp"..., 131072) = 70\nread(6, "", 131002) = 0\nclose(6) = 0\nstat("/proc/30849", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0\nopen("/proc/30849/stat", O_RDONLY) = 6\nread(6, "30849 (chrome) S 1 1750 1750 0 -"..., 2048) = 216\nclose(6) = 0\nopen("/proc/30849/status", O_RDONLY) = 6\nread(6, "Name:\\tchrome\\nState:\\tS (sleeping)"..., 2048) = 1005\nclose(6) = 0\nopen("/proc/30849/cmdline", O_RDONLY) = 6\nread(6, \nRun Code Online (Sandbox Code Playgroud)\n这是该命令输出的结尾,此时它以与其他ps命令冻结相同的方式冻结。
运行ps -q $pid -o args确实有效,列出指定 PID 的参数而不冻结。该标志使 ps 明确避免读取除指定进程之外的任何进程的进程文件。