2013-03-01 2 views
0

Я делаю программу, содержащую «Server.c», которая ждет, что клиент отправит ей сообщение SIGUSR1 10 раз, затем запустится и «client.c», который отправляет SIGUSR1 msg на сервер.«siginfo_t * info» сигнала «вызывает ошибку сегментации»

Проблема в том, что если я попытаюсь получить доступ к информации siginfo_t *, я получаю ошибку сегментации.

Обратите внимание, что это тестируется на сервере Debian ssh, на котором у меня нет высоких разрешений. Узел, который этот код отлично работает на Ubuntu.

Может ли siginfo_t * сбой информации из-за проблем с разрешением? Или есть еще одна проблема, вызывающая эту проблему переносимости. Насколько я знаю, libc должен быть достаточно стандартным во всех дистрибутивах linux, возможно, unix.

Любые идеи?

Благодаря

server.c

#include <signal.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <assert.h> 

int counter = 0; 
pid_t *clients = 0; 

void on_signal(int signo, siginfo_t *info, void * context) 
{ 
    puts("SIGNAL RECEIVED"); 
    assert(clients); 
    clients[counter] = info->si_pid; 
    ++counter; 
} 

int main() 
{ 
    struct sigaction action; 
    sigset_t set; 
    int recieveflag = 0; 

    clients = (pid_t*)malloc(10 * sizeof(pid_t)); 

    sigemptyset(&set); 
    sigaddset(&set, SA_SIGINFO); 

    memset(&action, 0, sizeof(struct sigaction)); 
    action.sa_sigaction = on_signal; 
    sigaction(SIGUSR1, &action, 0); 

    while (counter < 10) { 
     //sigprocmask(SIG_BLOCK, &set, 0); 
     sigsuspend(&set); 
    } 

    puts("I'm done!"); 

    return 0; 
} 

client.c:

#include <signal.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <assert.h> 

int main(int argc, const char** argv) 
{ 
    int server_id; 

    assert(argc == 2); 

    server_id = atoi(argv[1]); 
    assert(server_id > 0); 

    kill(server_id, SIGUSR1); 

    return 0; 
} 

Я попытался редактирование server.c на:

#include <signal.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <assert.h> 

int counter = 0; 
pid_t *clients = 0; 

void on_signal(int sig) 
{ 
    puts("SIGNAL RECEIVED"); 
} 

int main() 
{ 
    struct sigaction action; 
    sigset_t set; 
    int recieveflag = 0; 

    clients = (pid_t*)malloc(10 * sizeof(pid_t)); 

    sigemptyset(&set); 
    sigaddset(&set, SIGUSR1); 

    memset(&action, 0, sizeof(struct sigaction)); 
    action.sa_flags = SA_SIGINFO; 
    action.sa_handler = on_signal; 
    sigaction(SIGUSR1, &action, 0); 

    while (counter < 10) { 
     sigprocmask(SIG_BLOCK, &set, 0); 
     sigsuspend(&set); 
     ++counter; 
    } 

    puts("I'm done!"); 

    return 0; 
} 

теперь больше не принимает событие SIGUSR1 вообще.

ответ

4

Основным поведением sigaction является вызов простого обратного вызова, например: void (*sa_handler)(int);. Поэтому, если вы хотите использовать дескриптор sigaction с 3 параметрами void (*sa_sigaction)(int, siginfo_t *, void *);, вы должны установить поле sa_flags вашего синтаксиса структуры с флагом SA_SIGINFO. Взгляните на страницу руководства: http://www.kernel.org/doc/man-pages/online/pages/man2/sigaction.2.html кто ясен.

+0

На самом деле, возможно, вы правы, тестирование – Dmitry

+0

Извините, я не вижу, где он установлен. Если вы имеете в виду, что вы установили его 'sigaddset (& set, SA_SIGINFO);', sigaddset просто создайте список сигналов. в sigset_t. Таким образом, это не задает ни одного поля в вашей структуре sigaction. Также есть ошибка в вашем sigaddset, вы добавляете определение бита бит SA_SIGINFO, но это не сигнал ... – Hulor

+0

Вы правы, позвольте мне попытаться исправить это. – Dmitry

-1

setsigset, которые должны быть очищены и заполнены sigemptyset (и так один) его тот, который ВНУТРИ действие с именем action.sa_mask

sigemptyset(&action.sa_mask); 

попробовать и посмотреть, работает ли он