Programme reçu signal SIGPIPE, tuyau cassé.?

j'écris un programme client basé sur des sockets posix. Le programme crée plusieurs threads et va verrouiller le serveur. Mais pendant le debug dans le temps gdb le programme donne une info (erreur)

(gdb) n
Program received signal SIGPIPE, Broken pipe. [Switching to Thread 0xb74c0b40 (LWP 4864)] 0xb7fdd424 in __kernel_vsyscall () 
(gdb) 

voici le code:

#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

int get_hostname_by_ip(char* h , char* ip)
{
    struct hostent *he;
    struct in_addr **addr_list;
    int i;

    if ((he = gethostbyname(h)) == NULL) 
    {
        perror("gethostbyname");
        return 1;
    }
    addr_list = (struct in_addr **) he->h_addr_list;
    for(i = 0; addr_list[i] != NULL; i++) 
    {
        strcpy(ip , inet_ntoa(*addr_list[i]) );
        return 0;
    }

    return 1;
}

void client(char* h, int s)
{
    int fd;
    struct sockaddr_in addr;
    char ch[]="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    fd = socket(AF_INET, SOCK_STREAM, 0);
    addr.sin_family=AF_INET;
    char* ip = new char[20];
    get_hostname_by_ip(h, ip);
    addr.sin_addr.s_addr=inet_addr(ip);
    int port = 80;
    addr.sin_port=htons(port);
    if(connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) 
    {
        perror("connect error");
        return;
    }
    while(1)
    {
        if(send(fd, ch, sizeof(ch), 0) < 0)
        {   
            perror("send");
        }
    }
    //char buffer[1024];
    //if(recv(fd, &buffer, sizeof(buffer), 0) < 0)
    //{ 
    //  perror("recive");
    //}

    //printf("nReply from Server: %sn", buffer);
    close(fd);
}

struct info
{
    char* h;
    int c;
};


void* thread_entry_point(void* i)
{
    info* in = (info*)i;
    client(in->h, in->c);
}

int main(int argc, char** argv)
{
    int s = atoi(argv[2]);
    pthread_t t[s];
    info in = {argv[1], s};
    for(int i = 0; i < s; ++i)
    {
        pthread_create(&t[i], NULL, thread_entry_point, (void*)&in);
    }
    pthread_join(t[0], NULL);

    return 0;
}

Ce que c'est et que faire?

30
demandé sur alk 2013-09-21 21:24:25

5 réponses

le procédé a reçu un SIGPIPE . Le comportement par défaut pour ce signal est de mettre fin au processus.

A SIGPIPE est envoyé à un processus s'il a essayé d'écrire à une socket qui avait été arrêté pour écrire ou n'est pas connecté (plus).

Pour éviter que le programme se termine dans ce cas, vous pouvez soit

  • faire ignorer le processus SIGPIPE

    #include <signal.h>
    
    int main(void)
    {
      sigaction(SIGPIPE, &(struct sigaction){SIG_IGN}, NULL);
    
      ...
    

    ou

  • installez un gestionnaire explicite pour SIGPIPE (typiquement ne rien faire):

    #include <signal.h>
    
    void sigpipe_handler(int unused)
    {
    }
    
    int main(void)
    {
      sigaction(SIGPIPE, &(struct sigaction){sigpipe_handler}, NULL);
    
      ...
    

dans les deux cas send*() / write() retournerait -1 et établi errno à EPIPE .

33
répondu alk 2018-05-18 04:29:51

lors du débogage avec 'gdb', il est possible de désactiver manuellement SIGPIPE comme suit:

(gdb) handle SIGPIPE nostop

14
répondu Jason Chagas 2015-05-12 16:56:26

une solution de contournement pour SIGPIPE, vous pouvez ignorer ce signal par ce code:

#include <signal.h>

/* Catch Signal Handler functio */
void signal_callback_handler(int signum){

        printf("Caught signal SIGPIPE %d\n",signum);
}

dans votre code (principal ou mondial)

/* Catch Signal Handler SIGPIPE */
signal(SIGPIPE, signal_callback_handler);
12
répondu Hatem Mashaqi 2014-06-04 23:37:33

vous avez écrit à une connexion qui a déjà été fermée par le Pair.

4
répondu user207421 2013-09-22 01:03:00

j'ai en quelque sorte connu le même problème et il m'a laissé à ce poste. J'ai reçu des signaux SIGPIPE sporadiques causant des plantages de mon programme fastcgi c dirigé par nginx. J'ai essayé de signal(SIGPIPE, SIG_IGN); sans succès, il n'arrêtait pas de s'écraser.

la raison en était que le dir temporaire de nginx avait un problème de permission. La correction des permissions a résolu le problème SIGPIPE. Détails ici sur la façon de résoudre et plus ici .

3
répondu neoneye 2017-06-08 10:43:18