19

I am working on a networking program using epoll on linux machine and I got the error message from gdb.

Program received signal SIGPIPE, Broken pipe.
[Switching to Thread 0x7ffff609a700 (LWP 19788)]
0x00007ffff7bcdb2d in write () from /lib/libpthread.so.0
(gdb)
(gdb) backtrace
#0  0x00007ffff7bcdb2d in write () from /lib/libpthread.so.0
#1  0x0000000000416bc8 in WorkHandler::workLoop() ()
#2  0x0000000000416920 in WorkHandler::runWorkThread(void*) ()
#3  0x00007ffff7bc6971 in start_thread () from /lib/libpthread.so.0
#4  0x00007ffff718392d in clone () from /lib/libc.so.6
#5  0x0000000000000000 in ?? ()

My server doing n^2 time calculation and I tried to run the server with 500 connected users. What might cause this error? and how do I fix this?


       while(1){
            if(remainLength >= MAX_LENGTH)
                currentSentLength = write(client->getFd(), sBuffer, MAX_LENGTH);
            else
                currentSentLength = write(client->getFd(), sBuffer, remainLength);


            if(currentSentLength == -1){
                log("WorkHandler::workLoop, connection has been lost \n");
                break;
            }
            sBuffer += currentSentLength;
            remainLength -= currentSentLength;

            if(remainLength == 0)
                break;
        }
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
codereviewanskquestions
  • 13,460
  • 29
  • 98
  • 167
  • 6
    SIGPIPE happens when you try to write to a pipe that's been closed, make sure the pipe you're writing to is not closed. – Jesus Ramos Jul 26 '11 at 01:21
  • Post that as an answer so we can upvote it. It's as much answer as is possible given how little info is in the question. @LCYSoft: The GDB trace is useless without the code for the functions it calls out. – Mike DeSimone Jul 26 '11 at 01:25
  • No. Post a _testcase_. We're going to get hundreds of useless lines now. – Lightness Races in Orbit Jul 26 '11 at 01:25

2 Answers2

34

When you write to a pipe that has been closed (by the remote end) , your program will receive this signal. For simple command-line filter programs, this is often an appropriate default action, since the default handler for SIGPIPE will terminate the program.

For a multithreaded program, the correct action is usually to ignore the SIGPIPE signal, so that writing to a closed socket will not terminate the program.

Note that you cannot successfully perform a check before writing, since the remote end may close the socket in between your check and your call to write().

See this question for more information on ignoring SIGPIPE: How to prevent SIGPIPEs (or handle them properly)

Community
  • 1
  • 1
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • Sometimes you get a SIGPIPE because the remote end closed the connection *and never told you.* System crashes cause this a lot, since they don't clean up open sockets, so you don't know that the socket's gone until you write something to it and the remote end professes no knowledge of the connection. – Mike DeSimone Jul 26 '11 at 01:28
  • 2
    You can successfully perform the check just fine; you just can't _usefully_ do so. :) – Lightness Races in Orbit Jul 26 '11 at 01:30
  • @Tomalak Geret'kal no you can't. There is no Sockets API that will tell you other than trying an I/O operation. – user207421 Jul 26 '11 at 08:03
  • @EJP: Bah, that may be true. At least, the reason you gave in the third paragraph of your answer is not a valid reason. :) – Lightness Races in Orbit Jul 26 '11 at 13:22
  • @Tomalak Geret'kal it *is* true. No 'may be' about it. I assume you refer to the third paragraph in *Greg Hewgill's* answer? – user207421 Jul 27 '11 at 06:42
2

You're not catching SIGPIPE signals, but you're trying to write to a pipe that's been broken/closed.

Fairly self-explanatory.

It's usually sufficient to handle SIGPIPE signals as a no-op, and handle the error case around your write call in whatever application-specific manner you require... like this.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055