未接收使用sudo执行的进程的SIGCHLD
我目前正在写一个shell。我执行进程,并利用未接收使用sudo执行的进程的SIGCHLD,c,shell,exec,sudo,sigchld,C,Shell,Exec,Sudo,Sigchld,我目前正在写一个shell。我执行进程,并利用SIGCHLD信号处理程序在进程完成时进行清理(等待) 一切都在运行——除了我执行使用sudo升级权限的进程。在这些情况下,我从未得到一个SIGCHLD信号——因此我永远不知道进程已经完成执行 当我收到诸如sudo ls之类的命令时,我执行程序sudo,然后将ls作为参数提供。我使用execvp执行此执行 如果我在shell执行了sudo ls之后查看一下ps-aux,我会看到以下内容: root 4795 0.0 0.0 4496
SIGCHLD
信号处理程序在进程完成时进行清理(等待)
一切都在运行——除了我执行使用sudo
升级权限的进程。在这些情况下,我从未得到一个SIGCHLD
信号——因此我永远不知道进程已经完成执行
当我收到诸如sudo ls
之类的命令时,我执行程序sudo
,然后将ls
作为参数提供。我使用execvp
执行此执行
如果我在shell执行了sudo ls之后查看一下ps-aux,我会看到以下内容:
root 4795 0.0 0.0 4496 1160 pts/29 S+ 16:51 0:00 sudo ls
root 4796 0.0 0.0 0 0 pts/29 Z+ 16:51 0:00 [ls] <defunct>
root 4795 0.0 0.0 4496 1160 pts/29 S+16:51 0:00 sudo ls
根4796 0.0.0 pts/29 Z+16:51 0:00[ls]
因此,sudo
运行并被分配pid=4795
,子对象(ls)被分配4796
。孩子已经完成了任务,现在处于僵尸状态sudo
似乎不想收获僵尸进程,只是坐在那里
我想知道是什么导致了这种行为——我尝试了不同的技术来清理这些僵尸进程,比如在sudo
下运行shell,直接等待sudo
和sudo
执行的PID
(上例中为4796)。这些技术都不起作用
和往常一样,任何建议都是值得赞赏的。我的第一个想法是错误的信号处理,但您的帖子中没有足够的信息来编写测试代码来复制您的失败。但我可以给你一些地方看看。请原谅,如果我为将来的读者介绍一些你们已经知道的信号基础知识 首先,我不知道您是在使用传统的signal()还是新的POSIX sigaction()信号例程来捕获信号。sigset()是来自GNU的一个有用的中间变量 遗留信号--signal()
如果不是不可能的话,几乎不可能保证在所有环境中使用原始信号处理器的气密信号处理器
- 在某些UNIX系统上,输入信号处理程序可以将处理程序重置为默认条件。除非处理程序显式重置信号,否则后续信号将保证丢失。
- signal()处理程序不能假设每个信号调用一次。
- 处理程序必须执行
循环, 直到没有发现更多信号作为遗留信号,否则将设置布尔条件 表示至少有一个信号未完成。 实际计数未知。while((pid=waitpid(-1,&signal,WNOHANG))>0)
- 如果处理了先前的while()循环,则处理程序必须允许找不到任何信号 信号。
- 处理程序必须执行
- 允许来自未知进程的信号。。。如果你启动的程序也启动了 孙子进程如果您的孩子很快退出,您可能会继承该进程。
POSIX信号可以清除遗留信号的所有故障
- 设置一个处理程序,无需还原(还原不是POSIX信号的一部分,通常是, 至少在我看来,当你可能得到多个信号以同样的方式处理时是邪恶的)。
- sigaction()信号是粘性的。。。他们一直活着,直到有了明确的改变(太棒了!)。 所有这些都不需要重新设置信号处理程序 在处理程序中。
- 在处理信号时,设置遮罩以屏蔽当前信号。偏执狂还会掩盖传递给同一处理程序的任何其他信号。
GNU提供了一个有用的中间接口,它具有与signal()相同的调用签名,但消除了大多数问题。还提供了一些附加的控制功能。使用sigset()可以轻松解决许多信号问题 提醒
将信号处理程序视为程序中的线程, 即使代码中没有使用线程。 在过去的日子里,您需要在信号处理程序中进行绝对最小的处理。。。不调用库代码, 例如printf,有副作用。
在必须使用旧的信号处理程序时,我仍然遵循这一点,并且在较新的处理程序中始终使用多线程警告。我建议在由shell运行和由标准系统shell运行时,检查
strace(1)
sudo(8)的输出。由于跟踪会影响可执行文件上的setuid权限,所以需要在sudo
启动后但在它完成大量工作之前附加strace
sudo-k
首先将强制sudo
重新提示输入密码,当它等待时,您可以找到它的pid并运行strace-o/tmp/out-f-p
。这在其他shell下也会发生吗?@bdonlan,通过其他shell,您的意思是如果我通过bash运行sudo vi
?它并没有发生在那个里。你们可以试着阅读bash(或其他shell)的源代码,看看它有什么不同的地方/sudo有一些特殊的行为。此外,如果sudo更改了用户id,这是否会阻止您的流程使用sudo“执行工作人员”请求:向我们显示再现问题的最小可编译代码,并告诉我们sudo的版本,因为存在问题。问:当你执行时,你是否阻止了SIGCHLD<代码>sudo并不完全依赖CHLD,IIRC,但这肯定不会有什么帮助