返回

c-lldb 和信号的艰难时期,SIGSTOP 问题

发布时间:2022-05-17 15:37:38 259

我习惯了gdb.现在,当我换成FreeBSD,我试着用lldb.

该程序使用kqueue伺候SIGINTSIGTERM,SIGQUIT信号。现在如果lldb附加到进程,或使用调试器发送的命令行arg运行目标SIGSTOP信号一件事是SIGSTOP不能忽视和等待。

问题是kevent返回-1在流程中继续并继续退出。我看不到任何输出stderr,这是另一个在不同帖子中被问到的问题。

什么是处理信号的实践lldb是调试器吗?

使现代化

#include 
#include 
#include <netinet/in.h>
#include <sys/event.h>
#include <sys/socket.h>
#include <sys/time.h>
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include <yma/yerror.h>
#include <yma/ybsd_sock.h>

#define TERMINATE_SET(s, v, l) { EXPAND(s) = v; PRINT_ERROR() goto EXPAND(l);  }

#define NSIGNALS (5)
#define NSOCKETS (2)
#define SIGNALS  {SIGINT, SIGQUIT, SIGTERM, SIGCONT, SIGPIPE}
#define NKEVBACKLOG (NSIGNALS + (NSOCKETS * 4)) /* signals + socket reads/writes + socket error + eof */
#define BUFSIZE  (1024)

int main(int argc, char *argv[])
{
 (void)argc;
 (void)argv;

 /* program status */
 int status = 0;

 /* restore signals at program exit ? */
 bool b_restore_procmask = false;

 /* signal masks */
 sigset_t         mask_block_sigs, mask_save_sigs, mask_kqueue_sigs;

 struct kevent    chlist[10];            /* events to monitor */
 struct kevent    evlist[NKEVBACKLOG];   /* events that were triggered */
 int              kq = -1, i, n;

 /* signals being monitored by kqueue */
 int signals[] = SIGNALS;

  /* create kqueue descriptor */
  if((kq = kqueue()) < 0){
   TERMINATE_SET(status, -1, l_end)
  }

 /* set up signals */ 
 sigemptyset(&mask_block_sigs);
 /* these signals will be blocked. the signals will arrive */
 /* to kqueue and not to a default signal handler.          */
 for(i = 0; i < NSIGNALS; ++i){
  sigaddset(&mask_block_sigs, signals[i]);  
 }

 /* save old sigmask, replace it with new sigmask */
 status = sigprocmask(SIG_BLOCK, &mask_block_sigs, &mask_save_sigs);
 TERMINATE_IF(status < 0, l_end)

 b_restore_procmask = true;

 /* set signal event */
 for(i = 0; i < NSIGNALS; i++){
  EV_SET(&chlist[i], signals[i], EVFILT_SIGNAL, EV_ADD, 0, 0, 0);
 }
 /* end of signal setup */

 /* add signals change list to kqueue */
 n = kevent(kq, chlist, NSIGNALS, NULL, 0, NULL);
 if(n < 0){
  TERMINATE_SET(status, -1, l_end)
 }

 /* event loop */
 while( 1 ) {
  
  /* see event list */
  n = kevent(kq, NULL, 0, evlist, NKEVBACKLOG, NULL);

  switch(n) { /* switch on kevent return */
   /* timeout */
   case 0: 
    break;
   /* error */
   case -1:
    TERMINATE_SET(status, -1, l_end);
   /* some events */
   default: {
    int ev_id;
    
    /* process events */
    for(i = 0; i < n; ++i){
     ev_id = evlist[i].ident;

     /* check if signal has arrived */
     switch(ev_id){
      case SIGINT:
      printf(" ! got SIGINT\n");
      goto l_end;
     case SIGQUIT:
      printf(" ! got SIGQUIT\n");
      goto l_end;
     case SIGTERM:
      printf(" ! got SIGTERM\n");
      goto l_end;
     case SIGPIPE:
      printf(" ! got SIGPIPE\n");
      break;
     default: break;
    }
   } break; /* end process events */
  } /* end kevent return switch */
 } /* end event loop */

l_end:

 /* restore procmask */
 if(b_restore_procmask && (sigprocmask(SIG_SETMASK, &mask_save_sigs, NULL) < 0)){
  PRINT_ERROR()
 }
 /* close kqueue */
 CLOSE(kq);

 return status;
}

以上是等待POSIX信号的程序的完整源代码。

我不想包含我的 makefile,因为它在这里无关紧要。clang -std=c2x -Wall -Wpedantic -Wextra -Wfatal-errors -O0 -g3 -glldb -fpic -c kevent.c -o outp应该去的东西。

更新

该程序确实以“中断的系统调用”退出

更新

当我再次阅读代码时,我发现了一个错误。错误在于错误的ev_id初始化。初始化是在for事件循环之前。所以上面的代码会SIGINT按预期做出反应。

更新

但是,当我附加到进程而不是作为参数运行它时lldb,我再次感到困惑。如果我发送SIGINT到进程,lldb则忽略这一事实process handle SIGINT -s false -p true并以“中断的系统调用”退出。

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像