I write a client program based on posix sockets. The program creates multiple threads and is going to lock the server. But during debug in gdb time the program gives an info (error)
(gdb) n Program received signal SIGPIPE, Broken pipe. [Switching to Thread 0xb74c0b40 (LWP 4864)] 0xb7fdd424 in __kernel_vsyscall () (gdb)
Here's the 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: %s\n", 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;
}
What it is and what to do?
I sort of experienced the same problem and it let me to this SO post. I got sporadic SIGPIPE signals causing crashes of my fastcgi C program run by nginx. I tried to
signal(SIGPIPE, SIG_IGN);
without luck, it kept crashing.The reason was that nginx's temp dir had a permission problem. Fixing the permissions solved the SIGPIPE problem. Details here on how to fix and more here.
A workaround for SIGPIPE, you can ignore this signal by this code:
in your code (main or globally)
The process received a
SIGPIPE
. The default behaviour for this signal is to end the process.A
SIGPIPE
is sent to a process if it tried to write to a socket that had been shutdown for writing or isn't connected (anymore).To avoid that the program ends in this case, you could either
make the process ignore
SIGPIPE
or
install an explicit handler for
SIGPIPE
(typically doing nothing):In both cases
send*()
/write()
would return-1
and seterrno
toEPIPE
.When debugging with 'gdb', it is possible to manually disable SIGPIPE as follows:
(gdb) handle SIGPIPE nostop
You have written to a connection that has already been closed by the peer.