测试EINTR信号

时间:2012-09-14 12:27:14

标签: c gdb signals

在我的程序中,我有一个系统调用'sendmsg()'。我想测试一下如果系统调用中断会发生什么。我该怎么办?

int test(args) {
          -----
          /* I can use GDB and stop at this point */  
          n = sendmsg(h, send_msg, 0);
          ----
          return n; 
 }

 int test_caller(args) {
           int a, err;
           a = test(arg);
           if (a != what_i_am_expecting) {
               err = error;
               switch (err) {
                   case EINTR:
                       syslog(LOG_ERR, "I WANT TO SEE THIS LOG");
                       break;
                   default:
                }
            } else printf("Everything went well\n");
    return 0;
   } 

在同一个函数中,我按如下方式注册了一个信号处理程序:

1366         struct sigaction sa;
1367         
1368         memset (&sa, '\0', sizeof(sa));
1369         sa.sa_handler = sighdl;
1370         sa.sa_flags = 0; 
1371         (void)sigaction(SIGINT, &sa, NULL);

使用此处理程序:

1349 static void
1350 sighdl(int signo)
1351 {
1352         int i = 0;
1353         syslog(LOG_ERR, "got signal %d", signo);
1354         for (i = 0; i < 100; i++) {
1355         }
1356 }

我的想法是在调用sendmsg()之前中断test()函数,然后将sigint发送到pid。 但不确定这个signa;它是否在测试调用者中进入EINTR案例。

请帮忙!

1 个答案:

答案 0 :(得分:1)

通常sendmsg通话很快。因此很难在此期间发出信号。 但有一种方法:

根据协议sendmsg将阻止接收器队列是否已满。 因此,以某种方式填充队列,然后在程序卡在sendmsg调用中时按CTRL + C. (CTRL-C导致SIGINT)。

因为您捕获SIGINT,程序将不会退出。 sendmsg将返回代码-1和errno EINTR。