signal的“siginfo_t * info”导致分段错误

时间:2013-03-01 01:08:34

标签: c libc

我正在制作一个包含“Server.c”的程序,它等待客户端发送一次SI​​GUSR1消息10次,然后死掉,以及一个“client.c”,它将SIGUSR1消息发送给服务器。

问题是如果我尝试访问siginfo_t * info,我会遇到分段错误。

请注意,这是在我没有高权限的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事件。

1 个答案:

答案 0 :(得分: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谁很清楚。

相关问题