C 中的 WIFSIGNALED、WIFSTOPPED、WIFCONTINUED 测试用例

发布于 2024-07-21 09:58:21 字数 229 浏览 8 评论 0原文

我正在使用 waitpid() 和 signal() ,并且正在寻找返回 WIFSIGNALED(status) = WIFSTOPPED(status) = WIFCONTINUED (status) = true 的可靠测试用例,但找不到任何

...告诉我如何确保这些返回 true 以便我可以调试我的代码?

另外,关于我应该用 signal() 捕获哪些信号来测试这些宏的一些提示会很有帮助......

I'm playing with waitpid() and signal() and I'm looking for reliable test cases for returning WIFSIGNALED(status) = WIFSTOPPED(status) = WIFCONTINUED (status) = true but can't find any...

Care to tell me how can I make sure those return true so I can debug my code?

Also, a few hints about what signals should I catch with signal() to test those macros would be helpful...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

会发光的星星闪亮亮i 2024-07-28 09:58:21
#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;
}
#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;
}
灼疼热情 2024-07-28 09:58:21

处理 WIFSIGNALED 很容易。 子进程可以通过kill()系统调用自杀。 您还可以检查核心转储 - 一些信号创建它们(SIGQUIT、IIRC); 有些信号则不然(SIGINT)。

处理 WIFSTOPPED 可能会更困难。 尝试的简单步骤是让子进程再次通过 kill() 系统调用向自己发送 SIGSTOP。 事实上,我认为这应该有效。 请注意,您可能需要检查 SIGTTIN、SIGTTOU 和 SIGTSTOP - 我相信它们适用于 WIFSTOPPED。 (也有可能 SIGSTOP 只有在由调试器通过非 POSIX 系统调用 ptrace() 发送到正在运行的进程时才能正常工作。)

我认为处理 WIFCONTINUED 是父级的事情不得不做; 当您检测到进程已停止后,您的调用代码应该通过向其发送 SIGCONT 信号(再次kill())来使其继续。 孩子自己无法做到这一点; 它已被停止。 再说一遍,我不确定是否还有额外的皱纹需要担心——可能吧。

Handling WIFSIGNALED is easy. The child process can commit suicide with the kill() system call. You can also check for core dumps - some signals create them (SIGQUIT, IIRC); some signals do not (SIGINT).

Handling WIFSTOPPED may be harder. The simple step to try is for the child to send itself SIGSTOP with the kill() system call again. Actually, I think that should work. Note that you may want to check on SIGTTIN and SIGTTOU and SIGTSTOP - I believe they count for WIFSTOPPED. (There's also a chance that SIGSTOP only works sanely when sent by a debugger to a process it is running via the non-POSIX system call, ptrace().)

Handling WIFCONTINUED is something that I think the parent has to do; after you detect a process has been stopped, your calling code should make it continue by sending it a SIGCONT signal (kill() again). The child can't deliver this itself; it has been stopped. Again, I'm not sure whether there are extra wrinkles to worry about - probably.

苍暮颜 2024-07-28 09:58:21

类似于下面的框架将允许您检查 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) 和 < code>SIGINT for WIFSIGNALED(status)

如果您想要更灵活的测试,您可以使用kill(参见“mankill”)向您的设备发送信号。过程。 kill -l 将列出所有可以发送的信号。

A framework something like the below will allow you check the results of the wait() and waitpid() calls.

pid_t pid = fork();

if (pid == 0) {
    /* child */
    sleep(200);
}
else {
    /* parent */
    kill(pid, SIGSTOP);

    /* do wait(), waitpid() stuff */
}

You do not actually have to catch the signals (using signal() or related function) that are sent. signal() installs a handler that overrides the default behavior for the specific signal - so if you want to check for a signal terminating your process, pick one that has that default behavior - "man -s7 signal" will give you details a signal's default behavior.

For the macros you have mentioned use SIGSTOP for WIFSTOPPED(status), SIGCONT for WIFCONTINUED (status) and SIGINT for WIFSIGNALED(status)

If you want more flexibility for testing, you could use kill (see "man kill") to send signals to your process. kill -l will list all the signals that can be sent.

So尛奶瓶 2024-07-28 09:58:21

在您的测试中,您可以 fork() 并向您的子进程发送特定信号吗? 在这种情况下,您的子进程是测试用例?

编辑

我的答案是关于编写 C 测试。 你 fork 后,获取你的子进程的 pid(该进程
安装了信号处理程序),然后您可以使用 kill(2) 向其发送信号。
这样就可以测试退出状态

in your tests you can fork() and send specific signal to your child processes? In this scenario your child processes are test cases?

EDIT

my answer is about coding a C test. you fork, get the pid of your child process (the process
with signal handlers installed), then you can send signal to it by using kill(2).
In this way you can test the exit status

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文