проблемы с sig обработкой SIGSEGV - PullRequest
0 голосов
/ 28 марта 2012

Я создал обработчик сигнала для вызова при отправке SIGSEGV. Я использую C для написания своих программ, а также использую процессор Linux и Intel x86. В обработчике sig похоже, что si_addr, который передается через структуру siginfo_t, получает значение 0 вместо значения адреса инструкции, вызвавшей проблему. Я установил флаг SIG_INFO в sigaction, чтобы узнать, почему это происходит.

Вот пример кода:

int main(){
    mprotect(..., PROC_READ | PROC_WRITE /* | PROC_EXEC */);  //cannot execute page

    someMethodOnRestrictedPage();
    //do some stuff
}

void init_sighandler(void) {

    //initialize the sigaction so that sig handler is called when a SIGSEGV is thrown
    struct sigaction * action;

    action = (struct sigaction *) malloc(sizeof(struct sigaction));

    action->sa_sigaction = sighandler;
    sigemptyset (&action->sa_mask);

    action->sa_flags = 0;

    sigaddset(&action->sa_mask, SA_SIGINFO);
    sigaddset(&action->sa_mask, SA_RESTART);

    sigaction(SIGSEGV, action, NULL);
}

void sighandler(int sig, siginfo_t *siginfo, void *ucp){
    printf("%x\n", siginfo->si_addr);   // prints out 0
}

1 Ответ

1 голос
/ 28 марта 2012

У вашего .sa_flags бит SA_SIGINFO сброшен.

Цитирование http://pubs.opengroup.org/onlinepubs/7908799/xsh/sigaction.html,

SA_SIGINFO

Если сбросить и уловить сигнал, функция перехвата сигнала будет введена как:

void func(int signo);

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

Если установлено SA_SIGINFO и сигнал пойман, функция захвата сигнала будет введена как:

void func(int signo, siginfo_t *info, void *context);

где два дополнительных аргумента передаются в функцию перехвата сигнала. Второй аргумент будет указывать на объект типа siginfo_t, объясняющий причину, по которой был сгенерирован сигнал; третий аргумент может быть приведен к указателю на объект типа ucontext_t для ссылки на контекст принимающего процесса, который был прерван при доставке сигнала. В этом случае для описания функции перехвата сигнала необходимо использовать элемент sa_sigaction, а приложение не должно изменять элемент sa_handler.

Элемент si_signo содержит сгенерированный системой номер сигнала.

Элемент si_errno может содержать зависящую от реализации дополнительную информацию об ошибке; если не ноль, он содержит номер ошибки, идентифицирующий условие, которое вызвало генерирование сигнала.

Элемент si_code содержит код, определяющий причину сигнала. Если значение si_code меньше или равно 0, то сигнал был сгенерирован процессом, а si_pid и si_uid соответственно указывают идентификатор процесса и реальный идентификатор пользователя отправителя. Описание заголовка <signal.h> содержит информацию о содержании сигнала для элементов типа siginfo_t.

- Конечная цитата

Таким образом, sigaction использует .sa_handler, если бит очищен, и .sa_sigaction, если бит установлен.

То есть у вас неопределенное поведение, поскольку вы читаете неписанные аргументы.

Установите .sa_flags = SA_SIGINFO | ... для устранения проблемы.

...