0

クライアントがSIGUSR1メッセージを10回送信するのを待ってから死ぬ「Server.c」と、SIGUSR1メッセージをサーバーに送信する「client.c」を含むプログラムを作成しています。

問題は、siginfo_t* 情報にアクセスしようとすると、セグメンテーション違反が発生することです。

これは、私が高い権限を持っていない Debian ssh サーバーでテストされていることに注意してください。このコードが Ubuntu で正常に動作するノード。

パーミッションの問題で siginfo_t *info が失敗することはありますか? または、この移植性の問題を引き起こす別の問題があります。私が知る限り、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

1 に答える 1

4

sigaction の基本的な動作は、 : のような単純なコールバックを呼び出すことですvoid (*sa_handler)(int);。したがって、3 つのパラメーターvoid (*sa_sigaction)(int, siginfo_t *, void *);で sigaction ハンドルを使用する場合は、構造体 sigaction の sa_flags フィールドにフラグ SA_SIGINFO を設定する必要があります。man ページを見てみましょう: http://www.kernel.org/doc/man-pages/online/pages/man2/sigaction.2.html誰が明らかです。

于 2013-03-01T01:22:36.177 に答える