我正在使用waitpid()和signal(),我正在寻找可靠的测试用例来返回WIFSIGNALED(状态)= WIFSTOPPED(状态)= WIFCONTINUED(状态)= true但找不到任何..
请注意告诉我如何确保这些返回true,以便我可以调试我的代码?
另外,关于我应该用signal()检测哪些信号来测试这些宏的一些提示会有所帮助......
答案 0 :(得分:4)
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#define NELEMS(x) (sizeof (x) / sizeof (x)[0])
static void testsignaled(void) {
kill(getpid(), SIGINT);
}
static void teststopped(void) {
kill(getpid(), SIGSTOP);
}
static void testcontinued(void) {
kill(getpid(), SIGSTOP);
/* Busy-work to keep us from exiting before the parent waits.
* This is a race.
*/
alarm(1);
while(1) {}
}
int main(void) {
void (*test[])(void) = {testsignaled, teststopped, testcontinued};
pid_t pid[NELEMS(test)];
int i, status;
for(i = 0; i < sizeof test / sizeof test[0]; ++i) {
pid[i] = fork();
if(0 == pid[i]) {
test[i]();
return 0;
}
}
/* Pause to let the child processes to do their thing.
* This is a race.
*/
sleep(1);
/* Observe the stoppage of the third process and continue it. */
wait4(pid[2], &status, WUNTRACED, 0);
kill(pid[2], SIGCONT);
/* Wait for the child processes. */
for(i = 0; i < NELEMS(test); ++i) {
wait4(pid[i], &status, WCONTINUED | WUNTRACED, 0);
printf("%d%s%s%s\n", i, WIFCONTINUED(status) ? " CONTINUED" : "", WIFSIGNALED(status) ? " SIGNALED" : "", WIFSTOPPED(status) ? " STOPPED" : "");
}
return 0;
}
答案 1 :(得分:2)
轻松处理WIFSIGNALED。子进程可以通过kill()
系统调用自杀。您还可以检查核心转储 - 一些信号创建它们(SIGQUIT,IIRC);有些信号没有(SIGINT)。
处理WIFSTOPPED可能会更难。尝试的简单步骤是让孩子再次使用kill()
系统调用向自己发送SIGSTOP。实际上,我认为这应该有效。请注意,您可能需要检查SIGTTIN和SIGTTOU以及SIGTSTOP - 我相信它们会计入WIFSTOPPED。 (当调试器将调度程序发送到通过非POSIX系统调用ptrace()
运行的进程时,SIGSTOP也有可能正常工作。)
处理WIFCONTINUED是我认为父母必须做的事情;在您检测到进程已停止后,您的调用代码应通过向其发送SIGCONT信号(kill()
再次)继续进行。孩子不能自己提供这个;它已被停止。同样,我不确定是否还有额外的皱纹 - 可能。
答案 2 :(得分:1)
如下所示的框架可让您检查wait()
和waitpid()
来电的结果。
pid_t pid = fork();
if (pid == 0) {
/* child */
sleep(200);
}
else {
/* parent */
kill(pid, SIGSTOP);
/* do wait(), waitpid() stuff */
}
您实际上不必捕获已发送的信号(使用signal()
或相关函数)。 signal()
安装一个处理程序来覆盖特定信号的默认行为 - 因此,如果您要检查终止进程的信号,请选择具有该默认行为的信号 - “man -s7 signal
”将为您提供详细信息信号的默认行为。
对于您提到的宏,SIGSTOP
使用WIFSTOPPED(status)
,SIGCONT
使用WIFCONTINUED (status)
,SIGINT
使用WIFSIGNALED(status)
如果您想要更灵活的测试,可以使用kill(请参阅“man kill
”)向您的进程发送信号。 kill -l
将列出可以发送的所有信号。
答案 3 :(得分:-1)
在测试中你可以fork()并向你的子进程发送特定信号吗?在这种情况下,您的子进程是测试用例吗?
修改强>
我的答案是关于编码C测试。你分叉,得到你的孩子过程的pid(过程
安装了信号处理程序),然后您可以使用kill(2)
向其发送信号。
通过这种方式,您可以测试退出状态