Search code examples
linuxsignalssigpipe

General signal question with regards to expected behavior


Scenario 1

Lets say the following scenario exists.

My program makes a call to a 3rd party library which in turn calls another 3rd party library which turns around and makes OS calls.

   MyProgram
        |
   some3rdPartyFunction() ---> 3rd party library
                                 |
                             another3rdPartyFunction()----> another 3rd party library
                                                                      |
                                                                    OS call()

1st Set of Questions:

  • If this OS calls makes a socket call to a closed socket, what happens?
  • Is an error returned to the process making the OS call?
  • At what point does the system return a SIGPIPE message?
  • Does the SIGPIPE only get sent to the calling function or does the SIGPIPE get propagated all the way up to MyProgram?

Scenario 2

I happen to see the following output of a thread dump of a process.

rt_sigprocmask(SIG_SETMASK, ...)
rt_sigreturn({mask=[PIPE]})
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigaction(SIGINT, [], [], 8) = 0
rt_sigaction(SIGTERM, [], [], 8) = 0
rt_sigaction(SIGHUP, [], [], 8) = 0
rt_sigaction(SIGABRT, [], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], [], 8) = 0
rt_sigreturn({mask=[PIPE]})

2nd Set of Questions:

  • Why are so many signal messages being sent?
  • Would these be getting sent directly to MyProgram or being propagated up from the lower OS call?
  • With the variety of signals being sent, how to determine which one is actually causing the problem?

Solution

  • If this OS calls makes a socket call to a closed socket, what happens?

    Well, "closed" can be a bit misleading when talking about file descriptors (which may be closed) and stream sockets (like TCP, which may be partially or fully shut down). What I think you're asking about is a write() call error that POSIX documents as:

    [EPIPE] A write was attempted on a socket that is shut down for writing, or is no longer connected. In the latter case, if the socket is of type SOCK_STREAM, a SIGPIPE signal shall also be sent to the thread.

    Is an error returned to the process making the OS call?

    The error is returned to whatever bit of code called write, and the signal is generated for the thread that ultimately invoked the write.

    At what point does the system return a SIGPIPE message?

    The SIGPIPE is generated when attempting to write to an unwritable socket or pipe.

    Does the SIGPIPE only get sent to the calling function or does the SIGPIPE get propagated all the way up to MyProgram?

    The SIGPIPE is generated for the calling thread. Where it is in its call chain — your program, the 3rd-party library, etc. — is not germane to signal delivery.

    Why are so many signal messages being sent?

    None are being sent in what you show. Most of those calls are about masking and signal disposition, not signal generation. The rt_sigreturn calls tell you that Linux is handling the delivery of a SIGPIPE.

    Would these be getting sent directly to MyProgram or being propagated up from the lower OS call?

    I don't understand what this means. The SIGPIPE is generated for a specific thread in your process, whether your code in MyProgram is aware of that thread's existence, or whether the 3rd-party library "secretly" created the thread under the hood.

    With the variety of signals being sent, how to determine which one is actually causing the problem?

    There's only one signal generated in what you show, and that is a SIGPIPE.