我有一个基于FreeBSD 7
.由于某种原因,有时/usr/sbin/cli
(提供特定于供应商的 CLI 的可执行文件)及其子进程是孤立的(活着,但父进程是init
):
# ps -p 7173,7175,1 -o pid,ppid,start,user,command
PID PPID STARTED USER COMMAND
1 0 26Apr17 root /packages/mnt/jbase/sbin/init --
7173 1 31Dec17 test cli -c traceroute 10.10.98.8 as-number-lookup; quit
7175 7173 31Dec17 test /usr/sbin/traceroute -JA 10.10.98.8
#
如上所示,cli
(进程状态为idle
)是一个月前开始的。它是由sshd
(在用户下运行root
)启动的。当 SSH 客户端超时或断开连接时,sshd
进程向进程发送什么信号?进程能够忽略这个信号吗cli
?cli
我尝试truss
通过执行truss -f -p <cli PID>
然后断开 SSH 客户端来分析这一点,但没有信号发送到cli
.然后我退后一步并执行truss -f -p <sshd: freebsd@notty (sshd) PID>
(进程的父进程cli
)并杀死 SSH 客户端。这提供了以下调试输出:
1565: select(13,{ 3 5 7 10 12 },{ },0x0,0x0) = 1 (0x1)
1565: sigprocmask(SIG_BLOCK,{ SIGCHLD },{ }) = 0 (0x0)
1565: sigprocmask(SIG_SETMASK,{ },0x0) = 0 (0x0)
1565: clock_gettime(4,{ 5568.946095396 }) = 0 (0x0)
1565: read(3,"\M^]G)\M-=[\M^Y\M-Z\M-pD\M^O\M^]"...,16384) = 60 (0x3c)
1565: clock_gettime(13,{ 1517409641.000000000 }) = 0 (0x0)
1565: getpid() = 1565 (0x61d)
1565: socket(PF_LOCAL,SOCK_DGRAM,0) = 8 (0x8)
1565: fcntl(8,F_SETFD,FD_CLOEXEC) = 0 (0x0)
1565: connect(8,{ AF_UNIX "/var/run/logpriv" },106) ERR#13 'Permission denied'
1565: connect(8,{ AF_UNIX "/var/run/log" },106) = 0 (0x0)
1565: sendto(8,"<38>Jan 31 14:40:41 sshd[1565]: "...,106,0x0,NULL,0x0) = 106 (0x6a)
1565: close(8) = 0 (0x0)
1565: clock_gettime(13,{ 1517409641.000000000 }) = 0 (0x0)
1565: getpid() = 1565 (0x61d)
1565: socket(PF_LOCAL,SOCK_DGRAM,0) = 8 (0x8)
1565: fcntl(8,F_SETFD,FD_CLOEXEC) = 0 (0x0)
1565: connect(8,{ AF_UNIX "/var/run/logpriv" },106) ERR#13 'Permission denied'
1565: connect(8,{ AF_UNIX "/var/run/log" },106) = 0 (0x0)
1565: sendto(8,"<38>Jan 31 14:40:41 sshd[1565]: "...,74,0x0,NULL,0x0) = 74 (0x4a)
1565: close(8) = 0 (0x0)
1565: geteuid() = 1001 (0x3e9)
1565: unlink("/tmp/ssh-2A9AWQYCLZ/agent.1565") = 0 (0x0)
1565: rmdir(0x804024c40) = 0 (0x0)
1565: process exit, rval = 255
答案1
我不是 FreeBSD 用户,但这基本上是一个 Unix 问题......
每当一个进程的父进程死亡时,该进程就会成为孤立进程。这种情况经常发生,通常不是问题。父母去世并不会自动杀死孩子。
在 SSH(和 telnet 等)的特定情况下,当连接丢失时,shell 通常会收到 SIGHUP。正是它杀死了外壳,而不是成为孤儿。如果您的自定义 CLI 选择以非标准方式处理 SIGHUP(即不死),那么任何事情都可能发生。