Skip to content

ZMQ fails with "Interrupted system call" when a signal is delivered to the process #4837

@yurivict

Description

@yurivict

An application fails when it is waiting for a ZMQ message and a SIGALRM signal arrives.

The reason: errno=EINTR isn't properly handled. The system call poll() fails with errno=EINTR and it is being reported as an error, while the correct way to handle it is to re-run this call in such case.

Testcase:
long-zmq-poll-sleep.cpp

The above testcase waits forever until SIGALRM is sent to it from outside.

Once the signal is delivered it fails with this log:

$ ./long-zmq-poll-sleep 
SIGALRM handler installed
Initializing ZMQ context...
Creating PULL socket...
Binding to tcp://127.0.0.1:5555...
Socket bound. Calling recv() - this will sleep in poll() for a long time...
Waiting for messages (press Ctrl+C to interrupt, or send SIGALRM to test signal handling)...
PID: 55792

SIGALRM received (count: 1)
ZMQ recv() threw an exception: Interrupted system call (errno: 4)
Total SIGALRM signals received: 1

All system calls made by libzmq should be guarded and re-run when they fail with errno=EINTR.
This shouldn't be a responsibility of the caller of ZMQ functions to do this because every system call can fail like this.
libzmq itself should guard system calls.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions