Невозможно переназначить обработчик сигнала во второй раз - PullRequest
0 голосов
/ 23 июня 2019

У меня есть простой код, который использует два обработчика сигнала для сигнала «Ошибка сегментации». Первый работает, когда происходит сигнал, и после longjmp я переназначаю обработчик вторым для этого сигнала. К сожалению, поток кода не достигает необходимого обработчика, и я все еще получаю "Ошибка сегментации".

#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>

int i;
int ci;

jmp_buf m_env_buffer;
jmp_buf max_env_buffer;

void handler(int signum){
    printf("sigsegv on i:[%d]", i);
    ci = (++i);
    longjmp(m_env_buffer,1);
}

void top_handler(int signum){
    printf("sigsegv on max i:[%d]", i);
    longjmp(max_env_buffer,10);
}

int main(void) {
    signal(SIGSEGV, handler);
    char * pstart = "loremipsum";

    int m_cell = 0;
    char m_cell_v;

    int point;

    point = setjmp(m_env_buffer);
    if(point == 0){
            for(i=0; ;i--){
                    m_cell_v = pstart[i];
            }
    }

    //this wasn't invoked
    signal(SIGSEGV, top_handler);
    point = setjmp(max_env_buffer);
    if(point == 0){
            for(i=ci; ;i++){
                    char cur = pstart[i];
                    if(cur==10)
                            printf("\n");
                    printf("%c",cur);
            }
    }
    puts("finish");
    return 0;
}

1 Ответ

0 голосов
/ 23 июня 2019

signal() не следует использовать.У него ненадежная семантика.В вашей системе действие по умолчанию (завершение) выполняется при получении второго SIGSEGV.Второй вызов signal() фактически не имеет никакого эффекта.

Вместо него следует использовать sigaction().В вашем случае вы можете использовать следующую функцию вместо signal():

void set_signal (int signum, void (*handler)(int))
{
    struct sigaction act;

    act.sa_handler = handler;
    sigemptyset (&act.sa_mask);
    act.sa_flags = SA_NODEFER;
    act.sa_restorer = NULL;

    sigaction (signum, &act, NULL);
}

В будущем, прочитайте документацию в вашем распоряжении.Хороший источник - руководство glibc .В ней есть хорошая глава по обработке сигналов .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...