'Hard time with lldb and signals. SIGSTOP issue

I am used to gdb. Now, as I had switched to FreeBSD, I try to use lldb.

The program uses kqueue to wait on SIGINT, SIGTERM, SIGQUIT signals. Now if lldb attaches to the process, or runs target with command line arg, the debugger sends SIGSTOP signal. One thing is that SIGSTOP can't be ignored and wait on.

The problem is, that kevent returns -1 on process resume and proceeds to quit. I can not see no output to stderr, that is another question being asked in different post.

What is a practice to deal with signals when lldb is a debugger?

Update

#include <assert.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/event.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <stdbool.h>

#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;
}

The above is a complete source of a program that waits on POSIX signals.

I do not want to include my makefile, as it is irrelevant here. Something like clang -std=c2x -Wall -Wpedantic -Wextra -Wfatal-errors -O0 -g3 -glldb -fpic -c kevent.c -o outp should go.

Update

The program is indeed exits with "Interrupted system call"

Update

As I read again through the code, I've found an error. The error was in misplaced ev_id initialization. The initialization were before for event loop. So the above code reacts to SIGINT as expected.

Update

But again, when I attach to process, and not run it as an argument to lldb, I am being confused again. If I send SIGINT to the process, lldb is ignoring the fact that process handle SIGINT -s false -p true and quits with "Interrupted system call."



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source