GCC Code Coverage Report


Directory: ./
File: TESTS/TEST_ZMQ_ERRORS/main_interrupt.cpp
Date: 2026-01-23 17:10:06
Exec Total Coverage
Lines: 33 33 100.0%
Functions: 3 3 100.0%
Branches: 30 32 93.8%

Line Branch Exec Source
1 #include <iostream>
2 #include <thread>
3 #include <chrono>
4 #include <signal.h>
5 #include <zmq.hpp>
6 #include <unistd.h>
7 #include "data_stream_assert.h"
8
9 // Signal handler function (C style, not lambda)
10 volatile sig_atomic_t signal_received = 0;
11 1 void sigusr1_handler(int signum) {
12 1 signal_received = 1;
13 // No std::cout in signal handler - can cause crash!
14 1 }
15
16 // Test 1: EINTR - Simple test that zmq::poll() returns EINTR when interrupted by signal
17 1 void test_eintr(zmq::context_t& context) {
18
2/2
✓ Branch 0 (2→3) taken 1 times.
✓ Branch 2 (3→4) taken 1 times.
1 std::cout << "\n1. Test EINTR using zmq::poll() (simple signal interruption test):" << std::endl;
19 1 signal_received = 0;
20 1 int rc=0;
21
22 // Install a handler for SIGALRM that does not restart syscalls
23 struct sigaction old_action;
24 struct sigaction new_action;
25 1 new_action.sa_handler = sigusr1_handler; // Use C function, not lambda
26 1 sigemptyset(&new_action.sa_mask);
27 1 new_action.sa_flags = 0; // No SA_RESTART to force interruption
28 1 sigaction(SIGALRM, &new_action, &old_action);
29
30 try {
31
1/1
✓ Branch 0 (6→7) taken 1 times.
1 zmq::socket_t req_socket(context, ZMQ_REQ);
32
1/1
✓ Branch 0 (7→8) taken 1 times.
1 req_socket.connect("tcp://127.0.0.1:5554");
33
34
2/2
✓ Branch 0 (8→9) taken 1 times.
✓ Branch 2 (9→10) taken 1 times.
1 std::cout << " Setting up alarm to send SIGALRM in 1 second..." << std::endl;
35
36 // Use alarm() to send a signal after 1 second - simpler than threads
37 1 ualarm(5000, 0);
38
39
2/2
✓ Branch 0 (11→12) taken 1 times.
✓ Branch 2 (12→13) taken 1 times.
1 std::cout << " Calling zmq::poll() with infinite timeout..." << std::endl;
40
41 // Use zmq::poll() - should be interrupted by SIGALRM
42 1 zmq::pollitem_t items[] = { {req_socket.handle(), 0, ZMQ_POLLIN, 0} };
43
0/1
✗ Branch 0 (15→16) not taken.
1 rc = zmq::poll(items, 1, std::chrono::milliseconds(-1)); // Block indefinitely
44
1/2
✗ Branch 0 (41→42) not taken.
✓ Branch 1 (41→43) taken 1 times.
2 } catch (const zmq::error_t& e) {
45 // Cancel any pending alarm in case of exception
46 1 alarm(0);
47
48
7/7
✓ Branch 0 (45→46) taken 1 times.
✓ Branch 2 (47→48) taken 1 times.
✓ Branch 4 (48→49) taken 1 times.
✓ Branch 6 (50→51) taken 1 times.
✓ Branch 8 (51→52) taken 1 times.
✓ Branch 10 (52→53) taken 1 times.
✓ Branch 12 (53→54) taken 1 times.
1 std::cout << " Exception caught: " << e.what() << " (code: " << e.num() << ") should be EINTR: " << EINTR << std::endl;
49
4/4
✓ Branch 0 (56→57) taken 1 times.
✓ Branch 2 (59→60) taken 1 times.
✓ Branch 4 (62→63) taken 1 times.
✓ Branch 6 (64→65) taken 1 times.
5 data_stream_assert(e.num() == EINTR);
50 1 }
51
52
4/4
✓ Branch 0 (20→21) taken 1 times.
✓ Branch 2 (23→24) taken 1 times.
✓ Branch 4 (26→27) taken 1 times.
✓ Branch 6 (27→28) taken 1 times.
5 data_stream_assert(rc == 0);
53 // Restore original signal handler
54 1 sigaction(SIGALRM, &old_action, nullptr);
55 1 }
56
57 1 int main() {
58
1/1
✓ Branch 0 (2→3) taken 1 times.
1 zmq::context_t context(1);
59
60
2/2
✓ Branch 0 (3→4) taken 1 times.
✓ Branch 2 (4→5) taken 1 times.
1 std::cout << "=== Test error cases when sending ZMQ messages ===" << std::endl;
61
1/1
✓ Branch 0 (5→6) taken 1 times.
1 test_eintr(context);
62
63
2/2
✓ Branch 0 (6→7) taken 1 times.
✓ Branch 2 (7→8) taken 1 times.
1 std::cout << "\n✓ All interrupt tests passed" << std::endl;
64 1 return 0;
65 1 }
66