Расовые условия в моих обработчиках сигналов? (С) - PullRequest
1 голос
/ 02 апреля 2012

Я работаю в лаборатории оболочки для курса по Системам, и у меня были некоторые действительно странные ошибки в условиях гонки, которые я пытался устранить с вечера пятницы, и, похоже, не могу их исправить.

Мой текущий код: http://buu700.com/tsh

Все до START OF MY CODE и после END OF MY CODE предоставлено преподавателями курса, поэтому ни один из них не должен быть источником проблем.

У нас также есть тестовый скрипт;Вот результаты моих текущих испытаний: http://buu700.com/sdriver


/*****************
 * Signal handlers
 *****************/

/* 
 * sigchld_handler - The kernel sends a SIGCHLD to the shell whenever
 *     a child job terminates (becomes a zombie), or stops because it
 *     received a SIGSTOP, SIGTSTP, SIGTTIN or SIGTTOU signal. The 
 *     handler reaps all available zombie children, but doesn't wait 
 *     for any other currently running children to terminate.  
 */
void 
sigchld_handler(int sig) 
{
    pid_t pid;
    int status, termsig;
    struct job_t *job;


    sigset_t s;

    sigemptyset(&s);
    sigaddset(&s, SIGCHLD);
    sigaddset(&s, SIGINT);
    sigaddset(&s, SIGTSTP);

    sigprocmask(SIG_BLOCK, &s, NULL);


    while ((pid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
        if (WIFEXITED(status)) {
            deletejob(job_list, pid);
        }
        if ((termsig = WTERMSIG(status))) {
            deletejob(job_list, pid);
            safe_printf("Job [%i] (%i) %s by signal %i\n",
                            pid2jid(pid), pid, "terminated", termsig);
        }
        if (WIFSTOPPED(status)) {
            job = getjobpid(job_list, pid);
            job->state = ST;
            safe_printf("Job [%i] (%i) %s by signal %i\n",
                            pid2jid(pid), pid, "stopped", SIGTSTP);
        }
    }

    if (errno != ECHILD)
        unix_error("waitpid error");

    sigprocmask(SIG_UNBLOCK, &s, NULL);

    return;
}



/* 
 * sigint_handler - The kernel sends a SIGINT to the shell whenver the
 *    user types ctrl-c at the keyboard.  Catch it and send it along
 *    to the foreground job.  
 */
void 
sigint_handler(int sig) 
{
    sigset_t s;

    sigemptyset(&s);
    sigaddset(&s, SIGCHLD);
    sigaddset(&s, SIGINT);
    sigaddset(&s, SIGTSTP);

    sigprocmask(SIG_BLOCK, &s, NULL);

    kill(-1, sig);

    sigprocmask(SIG_UNBLOCK, &s, NULL);

    return;
}



/*
 * sigtstp_handler - The kernel sends a SIGTSTP to the shell whenever
 *     the user types ctrl-z at the keyboard. Catch it and suspend the
 *     foreground job by sending it a SIGTSTP.  
 */
void 
sigtstp_handler(int sig) 
{
    sigset_t s;

    sigemptyset(&s);
    sigaddset(&s, SIGCHLD);
    sigaddset(&s, SIGINT);
    sigaddset(&s, SIGTSTP);

    sigprocmask(SIG_BLOCK, &s, NULL);

    kill(-1, sig);

    sigprocmask(SIG_UNBLOCK, &s, NULL);

    return;
}

1 Ответ

1 голос
/ 02 апреля 2012

У меня есть подозрение, что ошибка связана с вашими гонками против других сигналов в ваших обработчиках сигналов:

sigint_handler(int sig) 
{
    sigset_t s;

    sigemptyset(&s);
    sigaddset(&s, SIGCHLD);
    sigaddset(&s, SIGINT);
    sigaddset(&s, SIGTSTP);

    sigprocmask(SIG_BLOCK, &s, NULL);

Когда вы регистрируете обработчик сигнала с помощью sigaction(2), вы можете указать sa_mask, которое ядро ​​будет использовать для блокировки сигналов во время работы вашего обработчика сигнала. Это делается атомарно и не требует дополнительной работы с вашей стороны. Просто заполните эту маску один раз при регистрации обработчика сигнала.

Другая возможность исходит от сигнала SIGTSTP; на странице 350 моей копии APUE, 2-е издание написано, частично:

Только оболочка управления заданиями должна сбрасывать расположение [SIGTSTP, SIGTTIN, SIGTTOU] на SIG_DFL.

В этих абзацах не сказано ничего, но я думаю, что справедливо предположить, что оболочка должна установить расположение сигнала на SIG_DFL для дочерних процессов - ей все равно нужно что-то сделать для обрабатывать сигналы самостоятельно.

Правильно ли вы справились с расположением сигналов у детей?

...