2013-03-01 91 views
0

我正在制作一个包含“Server.c”的程序,该程序等待客户端向其发送SIGUSR1消息10次,然后消失,并发送一个“client.c” SIGUSR1 msg到服务器。信号的“siginfo_t *信息”导致分段错误

问题是,如果我尝试访问siginfo_t * info,则会出现分段错误。

请注意,这是在一个Debian ssh服务器上测试的,我没有很高的权限。 此代码在Ubuntu上正常工作的节点。

由于权限问题,siginfo_t * info是否失败?还是有另一个问题导致这种可移植性问题。据我所知,在任何Linux发行版中,libc都应该是相当标准的,可能是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);。因此,如果您想使用带3个参数void (*sa_sigaction)(int, siginfo_t *, void *);的sigaction句柄,则必须使用SA_SIGINFO标志设置struct sigaction的sa_flags字段。看看手册页:http://www.kernel.org/doc/man-pages/online/pages/man2/sigaction.2.html谁清楚。

+0

实际上,你可能是对的,测试 – Dmitry 2013-03-01 01:32:00

+0

对不起,我没有看到它的设置。如果你的意思是你用'sigaddset(&set,SA_SIGINFO)'设置它,'sigaddset只是创建一个信号列表。进入sigset_t。所以这不会在你的struct sigaction上设置任何字段。你的sigaddset还有一个错误,你添加一个位标志SA_SIGINFO的定义,但这不是一个信号... – Hulor 2013-03-01 01:38:05

+0

你说得对,让我试着去修复它。 – Dmitry 2013-03-01 01:41:46

-1

setsigset必须清空并充满sigemptyset(等一个)其一个是 INSIDE行动action.sa_mask名

sigemptyset(&action.sa_mask); 

尝试,看看它是否工作