misc/129172: signals are not delivered always

Roman Roman.Gritsulyak at gmail.com
Tue Nov 25 04:30:10 PST 2008


>Number:         129172
>Category:       misc
>Synopsis:       signals are not delivered always
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Nov 25 12:30:09 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Roman
>Release:        6.3-RELEASE FreeBSD 6.3-RELEASE
>Organization:
>Environment:
FreeBSD host.myrtghost.ru 6.3-RELEASE FreeBSD 6.3-RELEASE #0: Wed Jan 16 01:43:02 UTC 2008     root at palmer.cse.buffalo.edu:/usr/obj/usr/src/sys/SMP  amd64
>Description:
Seems, that signals that had been set by sigaction, or just by signal are not robust.

Child counts is 100 in following example.

Just 39 childs in following test appeared.

If we remove protection by semaphore, it was just about 17 signals catched.

Under linux all 100 childs signals passed in signal handler, and worked fine for both tests.


>How-To-Repeat:
Compile sem kernel module and load it into the kernel.
gcc3.4 used

gcc sigsem3.c -o sigsem3
./signal3
 - not all signals processed.

gcc sigsem2.c -o sigsem2
./signal2

coredump obtained.

gcc sigsem1.c -o sigsem1
./signal1

sigsem3.c:
==cut==%<==========
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <semaphore.h>

volatile int chld_count;

sem_t asem;

void handler(int sig)
{
  pid_t pid;
  sem_wait(&asem);
  chld_count ++;
  pid = wait(NULL);

  printf("Pid %d exited. count: %d\n", pid, chld_count);
  sem_post(&asem);
}

int main(void)
{
  int i;
  chld_count=0;
  struct sigaction sa;
  sem_init(&asem,0,1);

  signal(SIGCHLD, handler);

  sigemptyset(&sa.sa_mask);
  sa.sa_flags = SA_RESTART;
  sa.sa_handler = handler;

  sigaction(SIGCHLD, &sa, NULL);

  for(i=0;i<100;i++)
  {
          int ret_val;
          ret_val=fork();

          if(ret_val==-1)
          {
                  perror("fork()");
          }
          else if(!ret_val)
          {
                  printf("in child;Child pid is %d\n", getpid());
                  exit(0);
          }
          else
          {
                  printf("Parent pid is %d; child is %d;\n",
                                  getpid(),ret_val);
          }
  }

  return 0;
}

==cut==>%==========
sigsem2.c:
==========
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <semaphore.h>
// linux: -lpthread
volatile int chld_count;

sem_t asem;

void handler(int sig)
{
  pid_t pid;
  sem_wait(&asem);
  chld_count ++;
  pid = wait(NULL);

  printf("Pid %d exited. count: %d\n", pid, chld_count);
  sem_post(&asem);
}

int main(void)
{
  int i;
  chld_count=0;

  sem_init(&asem,0,1);

  signal(SIGCHLD, handler);

  for(i=0;i<100;i++)
  {
          int ret_val;
          ret_val=fork();

          if(ret_val==-1)
          {
                  perror("fork()");
          }
          else if(!ret_val)
          {
                  printf("in child;Child pid is %d\n", getpid());
                  exit(0);
          }
          else
          {
                  printf("Parent pid is %d; child is %d;\n",
                                  getpid(),ret_val);
          }
  }

  return 0;
}
==cut==>%==========



>Fix:


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list