The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Не обрабатывается сигнал после предыдущего."
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (C/C++)
Изначальное сообщение [ Отслеживать ]

"Не обрабатывается сигнал после предыдущего."  +/
Сообщение от CROSP email(ok) on 19-Ноя-14, 14:56 
Здравствуйте, возникла такая проблема. Тестирую работу сигналов. Посылаю различные сигналы при определенных параметры. Проблема, в том что, почему-то , после посылки второго сигнала отказывается обрабатываться другой. Лучше покажу на коде.

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <cstdlib>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <dirent.h>
#include <signal.h>
#include <elf.h>
#include <errno.h>
void checkIfExists(pid_t pid);
struct sigaction sig_4,sig_11,sig_12,old_sa12;
sigset_t new_mask;
sigset_t old_mask;
// Обработчики сигналов
void signal4_SIGILL(int sig) {
    printf("Signal SIGILL 4 has been received from parent %d and my pid is %d \n",getppid(),getpid());
}
void signal12_SIGUSR2(int sig) {
    printf("Signal SIGUSR2 12 has been received from parent %d and my pid is %d \n",getppid(),getpid());
}
void signal11_SIGSEGV(int sig) {
    printf("Signal SIGSEGV 11 has been received from parent %d and my pid is %d \n",getppid(),getpid());
    printf("Going to do some useless stuff to delay execution \n");
    sleep(1);
    printf("After perfoming stuff\n");

}
int main()
{
    pid_t pid;
    printf("program start...\n");
    pid = fork();
    if (pid == -1 )
    {
        printf("error, process has no craete...\n");
        return 1;    
    }
    if (pid == 0)
    {
        
        printf("Child creation...\n");
        memset (&sig_4, '\0', sizeof(sig_4)); // Выделяем место и заполняем нулями для структур
        memset (&sig_11, '\0', sizeof(sig_11));
        memset (&sig_12, '\0', sizeof(sig_12));
        sig_4.sa_handler = &signal4_SIGILL; // Устанавливаем обработчик для сигнала 4
        sig_4.sa_flags=SA_NODEFER; // Разрешаем вызов сигнала из его же обработчика
        sig_11.sa_handler = &signal11_SIGSEGV;
        sig_11.sa_flags=SA_NODEFER;
        sig_12.sa_handler = &signal12_SIGUSR2;
        sig_12.sa_flags = SA_NODEFER|SA_RESETHAND; // Устанавливаем стандартный обработчик после первого получения
        if (sigaction(SIGILL, &sig_4, NULL) < 0) { // Устанавливаем новую структуру для определенного сигнала
            perror ("sigaction"); // Если произошла ошибка
        return 1;
        }
        if (sigaction(SIGSEGV, &sig_11, NULL) < 0) {
            perror ("sigaction");
        return 1;
        }
        if (sigaction(SIGUSR2, &sig_12,&old_sa12 ) < 0) {
            perror ("sigaction");
        return 1;
        }
        if (sigemptyset(&new_mask)) {  // Заполняем структуру маски (нулями)
         return 1;  
     }
     if (sigaddset(&new_mask, SIGILL)) { // Добавляем в маску номер сигнала для блокировки
         return 1;  
     }  
        printf("Trying to set mask for process \n"); // Устанавливаем маску для процесса
     if (sigprocmask(SIG_BLOCK, &new_mask, NULL)) {  
         return 1;  
     }  
        // Данный участок кода для временного блокирования сигнала для процесса.
        //printf("In masked section for signal SIGILL, trying to sleep \n");
        //sleep(3);
        //printf("In masked section for signal SIGILL, after sleep \n");
        
  
     //if (sigprocmask(SIG_UNBLOCK, &new_mask, NULL)) {  
         //return 1;  
     //}  
  
        while(true) {};
        
        printf("Child end ...\n");
    }
    else
    {
            sleep(2);
            printf("i`m parеnt, id=%d\n",getpid());
            sleep(1);
            printf("starting to send signal...\n");
            printf("send SIG_4\n");
            if (kill(pid,4)<0){printf("send signal failed\n");} // Посылаем сигнал дочернему процессу
            sleep(1); // Спим для задержки
            printf("send SIG_11\n");
            if (kill(pid,11)<0){printf("send signal failed\n");}
            sleep(1);
            printf("send second SIG_11\n");
            if (kill(pid,11)<0){printf("send signal failed\n");}
            sleep(1);
        
            printf("send SIG_12\n");
            if (kill(pid,12)<0){printf("send signal failed\n");} // Посылаем сигнал №12, в его обработчике устанавливем  по умолчанию
            sleep(1);
            printf("send second SIG_12 after restoring to default handler\n");
            if (kill(pid,12)<0){printf("send signal failed\n");} // Посылаем еще раз сигнал №12
            sleep(1);
            checkIfExists(pid);
            printf("Sending signals and allowing to catch inside same handler\n");
            printf("I am going to send a lot of requests to SIG11 to test handling signals in predefined handler\n");
  printf("send again SIG_11\n");
                        if (kill(pid,11)<0){printf("send signal failed\n");}
            checkIfExists(pid);
                        sleep(2);
    
        /*    for (int i=0;i<10;i++) {
            if(kill(pid,11)<0){printf("send signal failed\n");}
            }
            */
            kill(pid,11);
            if (kill(pid,9)<0){printf("send signal failed\n");} // Killing child process
            sleep(1);
    }

    
}

void checkIfExists(pid_t pid) {

    kill(pid,0);
         if(errno == ESRCH) {
                    printf("The  pid or process does not exist.\n");
               
            }
else {
    printf("Process exists \n");
}
}

Собственно тут посылаю различные сигналы при определенных масках и обработчиках для каждого сигнала. Проблема в том что строчка  

  printf("send again SIG_11\n");
                        if (kill(pid,11)<0){printf("send signal failed\n");}
не выполняется если перед этим был подан сигнал 12. В сигнале 12 стоят флаги sig_12.sa_flags = SA_NODEFER|SA_RESETHAND; если убрать SA_RESETHAND все работает, а если оставить только его, то тоже не работает. Смотрел вроде же SA_RESETHAND восстанавливает только для одного сигнала дефолтный обработчик.
Вывод в консоль следующий.


program start...
Child creation...
Trying to set mask for process  
i`m parеnt, id=9502
starting to send signal...
send SIG_4
send SIG_11
Signal SIGSEGV 11 has been received from parent 9502 and my pid is 9503  
Going to do some useless stuff to delay execution  
After perfoming stuff
send second SIG_11
Signal SIGSEGV 11 has been received from parent 9502 and my pid is 9503  
Going to do some useless stuff to delay execution  
send SIG_12
After perfoming stuff
Signal SIGUSR2 12 has been received from parent 9502 and my pid is 9503  
send second SIG_12 after restoring to default handler
Process exists  
Third iteration sending signals and allowing to catch inside same handler
I am going to send a lot of requests to SIG11 to test handling signals in predefined handler
send second SIG_11

Process exists

Подскажите пожалуйста в чем может быть проблема ?

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Не обрабатывается сигнал после предыдущего."  +/
Сообщение от pavlinux (ok) on 21-Ноя-14, 22:25 
> Подскажите пожалуйста в чем может быть проблема ?

Ещё раз код, но без комментов, printf, sleep, и include ТОЛЬКО нужные

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

2. "Не обрабатывается сигнал после предыдущего."  +/
Сообщение от CROSP email(ok) on 21-Ноя-14, 22:33 
>> Подскажите пожалуйста в чем может быть проблема ?
> Ещё раз код, но без комментов, printf, sleep, и include ТОЛЬКО нужные

Здравствуйте, спасибо за ответ. Проблема была тривиальная. Просто недосмотрел дефолтную реакцию на сигнал USR2 - это termination. Соответственно процесс дочерний уничтожался. Но проверка с помощью посылки 0 сигнала проходила. Я как-то затупил тут. Потом с помощью strace посмотрел после дефолтного обработчика вызов системный идет SIGCHLD с кодом завершения.
Спасибо.

Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

3. "Не обрабатывается сигнал после предыдущего."  +/
Сообщение от pavlinux (ok) on 21-Ноя-14, 22:36 
> Проблема была тривиальная.

Покурить доки на тему кто такие 9, 11 и вроде 18 сигналы.


Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру