Coverage Report

Created: 2025-07-01 06:07

/src/libzmq/src/err.cpp
Line
Count
Source (jump to first uncovered line)
1
/* SPDX-License-Identifier: MPL-2.0 */
2
3
#include "precompiled.hpp"
4
#include "err.hpp"
5
#include "macros.hpp"
6
7
const char *zmq::errno_to_string (int errno_)
8
0
{
9
0
    switch (errno_) {
10
#if defined ZMQ_HAVE_WINDOWS
11
        case ENOTSUP:
12
            return "Not supported";
13
        case EPROTONOSUPPORT:
14
            return "Protocol not supported";
15
        case ENOBUFS:
16
            return "No buffer space available";
17
        case ENETDOWN:
18
            return "Network is down";
19
        case EADDRINUSE:
20
            return "Address in use";
21
        case EADDRNOTAVAIL:
22
            return "Address not available";
23
        case ECONNREFUSED:
24
            return "Connection refused";
25
        case EINPROGRESS:
26
            return "Operation in progress";
27
#endif
28
0
        case EFSM:
29
0
            return "Operation cannot be accomplished in current state";
30
0
        case ENOCOMPATPROTO:
31
0
            return "The protocol is not compatible with the socket type";
32
0
        case ETERM:
33
0
            return "Context was terminated";
34
0
        case EMTHREAD:
35
0
            return "No thread available";
36
0
        case EHOSTUNREACH:
37
0
            return "Host unreachable";
38
0
        default:
39
#if defined _MSC_VER
40
#pragma warning(push)
41
#pragma warning(disable : 4996)
42
#endif
43
0
            return strerror (errno_);
44
#if defined _MSC_VER
45
#pragma warning(pop)
46
#endif
47
0
    }
48
0
}
49
50
void zmq::zmq_abort (const char *errmsg_)
51
0
{
52
#if defined ZMQ_HAVE_WINDOWS
53
54
    //  Raise STATUS_FATAL_APP_EXIT.
55
    ULONG_PTR extra_info[1];
56
    extra_info[0] = (ULONG_PTR) errmsg_;
57
    RaiseException (0x40000015, EXCEPTION_NONCONTINUABLE, 1, extra_info);
58
#else
59
0
    LIBZMQ_UNUSED (errmsg_);
60
0
    print_backtrace ();
61
0
    abort ();
62
0
#endif
63
0
}
64
65
#ifdef ZMQ_HAVE_WINDOWS
66
67
const char *zmq::wsa_error ()
68
{
69
    return wsa_error_no (WSAGetLastError (), NULL);
70
}
71
72
const char *zmq::wsa_error_no (int no_, const char *wsae_wouldblock_string_)
73
{
74
    //  TODO:  It seems that list of Windows socket errors is longer than this.
75
    //         Investigate whether there's a way to convert it into the string
76
    //         automatically (wsaError->HRESULT->string?).
77
    switch (no_) {
78
        case WSABASEERR:
79
            return "No Error";
80
        case WSAEINTR:
81
            return "Interrupted system call";
82
        case WSAEBADF:
83
            return "Bad file number";
84
        case WSAEACCES:
85
            return "Permission denied";
86
        case WSAEFAULT:
87
            return "Bad address";
88
        case WSAEINVAL:
89
            return "Invalid argument";
90
        case WSAEMFILE:
91
            return "Too many open files";
92
        case WSAEWOULDBLOCK:
93
            return wsae_wouldblock_string_;
94
        case WSAEINPROGRESS:
95
            return "Operation now in progress";
96
        case WSAEALREADY:
97
            return "Operation already in progress";
98
        case WSAENOTSOCK:
99
            return "Socket operation on non-socket";
100
        case WSAEDESTADDRREQ:
101
            return "Destination address required";
102
        case WSAEMSGSIZE:
103
            return "Message too long";
104
        case WSAEPROTOTYPE:
105
            return "Protocol wrong type for socket";
106
        case WSAENOPROTOOPT:
107
            return "Bas protocol option";
108
        case WSAEPROTONOSUPPORT:
109
            return "Protocol not supported";
110
        case WSAESOCKTNOSUPPORT:
111
            return "Socket type not supported";
112
        case WSAEOPNOTSUPP:
113
            return "Operation not supported on socket";
114
        case WSAEPFNOSUPPORT:
115
            return "Protocol family not supported";
116
        case WSAEAFNOSUPPORT:
117
            return "Address family not supported by protocol family";
118
        case WSAEADDRINUSE:
119
            return "Address already in use";
120
        case WSAEADDRNOTAVAIL:
121
            return "Can't assign requested address";
122
        case WSAENETDOWN:
123
            return "Network is down";
124
        case WSAENETUNREACH:
125
            return "Network is unreachable";
126
        case WSAENETRESET:
127
            return "Net dropped connection or reset";
128
        case WSAECONNABORTED:
129
            return "Software caused connection abort";
130
        case WSAECONNRESET:
131
            return "Connection reset by peer";
132
        case WSAENOBUFS:
133
            return "No buffer space available";
134
        case WSAEISCONN:
135
            return "Socket is already connected";
136
        case WSAENOTCONN:
137
            return "Socket is not connected";
138
        case WSAESHUTDOWN:
139
            return "Can't send after socket shutdown";
140
        case WSAETOOMANYREFS:
141
            return "Too many references can't splice";
142
        case WSAETIMEDOUT:
143
            return "Connection timed out";
144
        case WSAECONNREFUSED:
145
            return "Connection refused";
146
        case WSAELOOP:
147
            return "Too many levels of symbolic links";
148
        case WSAENAMETOOLONG:
149
            return "File name too long";
150
        case WSAEHOSTDOWN:
151
            return "Host is down";
152
        case WSAEHOSTUNREACH:
153
            return "No Route to Host";
154
        case WSAENOTEMPTY:
155
            return "Directory not empty";
156
        case WSAEPROCLIM:
157
            return "Too many processes";
158
        case WSAEUSERS:
159
            return "Too many users";
160
        case WSAEDQUOT:
161
            return "Disc Quota Exceeded";
162
        case WSAESTALE:
163
            return "Stale NFS file handle";
164
        case WSAEREMOTE:
165
            return "Too many levels of remote in path";
166
        case WSASYSNOTREADY:
167
            return "Network SubSystem is unavailable";
168
        case WSAVERNOTSUPPORTED:
169
            return "WINSOCK DLL Version out of range";
170
        case WSANOTINITIALISED:
171
            return "Successful WSASTARTUP not yet performed";
172
        case WSAHOST_NOT_FOUND:
173
            return "Host not found";
174
        case WSATRY_AGAIN:
175
            return "Non-Authoritative Host not found";
176
        case WSANO_RECOVERY:
177
            return "Non-Recoverable errors: FORMERR REFUSED NOTIMP";
178
        case WSANO_DATA:
179
            return "Valid name no data record of requested";
180
        default:
181
            return "error not defined";
182
    }
183
}
184
185
void zmq::win_error (char *buffer_, size_t buffer_size_)
186
{
187
    const DWORD errcode = GetLastError ();
188
#if defined _WIN32_WCE
189
    DWORD rc = FormatMessageW (
190
      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errcode,
191
      MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR) buffer_,
192
      buffer_size_ / sizeof (wchar_t), NULL);
193
#else
194
    const DWORD rc = FormatMessageA (
195
      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errcode,
196
      MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), buffer_,
197
      static_cast<DWORD> (buffer_size_), NULL);
198
#endif
199
    zmq_assert (rc);
200
}
201
202
int zmq::wsa_error_to_errno (int errcode_)
203
{
204
    switch (errcode_) {
205
            //  10004 - Interrupted system call.
206
        case WSAEINTR:
207
            return EINTR;
208
            //  10009 - File handle is not valid.
209
        case WSAEBADF:
210
            return EBADF;
211
            //  10013 - Permission denied.
212
        case WSAEACCES:
213
            return EACCES;
214
            //  10014 - Bad address.
215
        case WSAEFAULT:
216
            return EFAULT;
217
            //  10022 - Invalid argument.
218
        case WSAEINVAL:
219
            return EINVAL;
220
            //  10024 - Too many open files.
221
        case WSAEMFILE:
222
            return EMFILE;
223
            //  10035 - Operation would block.
224
        case WSAEWOULDBLOCK:
225
            return EBUSY;
226
            //  10036 - Operation now in progress.
227
        case WSAEINPROGRESS:
228
            return EAGAIN;
229
            //  10037 - Operation already in progress.
230
        case WSAEALREADY:
231
            return EAGAIN;
232
            //  10038 - Socket operation on non-socket.
233
        case WSAENOTSOCK:
234
            return ENOTSOCK;
235
            //  10039 - Destination address required.
236
        case WSAEDESTADDRREQ:
237
            return EFAULT;
238
            //  10040 - Message too long.
239
        case WSAEMSGSIZE:
240
            return EMSGSIZE;
241
            //  10041 - Protocol wrong type for socket.
242
        case WSAEPROTOTYPE:
243
            return EFAULT;
244
            //  10042 - Bad protocol option.
245
        case WSAENOPROTOOPT:
246
            return EINVAL;
247
            //  10043 - Protocol not supported.
248
        case WSAEPROTONOSUPPORT:
249
            return EPROTONOSUPPORT;
250
            //  10044 - Socket type not supported.
251
        case WSAESOCKTNOSUPPORT:
252
            return EFAULT;
253
            //  10045 - Operation not supported on socket.
254
        case WSAEOPNOTSUPP:
255
            return EFAULT;
256
            //  10046 - Protocol family not supported.
257
        case WSAEPFNOSUPPORT:
258
            return EPROTONOSUPPORT;
259
            //  10047 - Address family not supported by protocol family.
260
        case WSAEAFNOSUPPORT:
261
            return EAFNOSUPPORT;
262
            //  10048 - Address already in use.
263
        case WSAEADDRINUSE:
264
            return EADDRINUSE;
265
            //  10049 - Cannot assign requested address.
266
        case WSAEADDRNOTAVAIL:
267
            return EADDRNOTAVAIL;
268
            //  10050 - Network is down.
269
        case WSAENETDOWN:
270
            return ENETDOWN;
271
            //  10051 - Network is unreachable.
272
        case WSAENETUNREACH:
273
            return ENETUNREACH;
274
            //  10052 - Network dropped connection on reset.
275
        case WSAENETRESET:
276
            return ENETRESET;
277
            //  10053 - Software caused connection abort.
278
        case WSAECONNABORTED:
279
            return ECONNABORTED;
280
            //  10054 - Connection reset by peer.
281
        case WSAECONNRESET:
282
            return ECONNRESET;
283
            //  10055 - No buffer space available.
284
        case WSAENOBUFS:
285
            return ENOBUFS;
286
            //  10056 - Socket is already connected.
287
        case WSAEISCONN:
288
            return EFAULT;
289
            //  10057 - Socket is not connected.
290
        case WSAENOTCONN:
291
            return ENOTCONN;
292
            //  10058 - Can't send after socket shutdown.
293
        case WSAESHUTDOWN:
294
            return EFAULT;
295
            //  10059 - Too many references can't splice.
296
        case WSAETOOMANYREFS:
297
            return EFAULT;
298
            //  10060 - Connection timed out.
299
        case WSAETIMEDOUT:
300
            return ETIMEDOUT;
301
            //  10061 - Connection refused.
302
        case WSAECONNREFUSED:
303
            return ECONNREFUSED;
304
            //  10062 - Too many levels of symbolic links.
305
        case WSAELOOP:
306
            return EFAULT;
307
            //  10063 - File name too long.
308
        case WSAENAMETOOLONG:
309
            return EFAULT;
310
            //  10064 - Host is down.
311
        case WSAEHOSTDOWN:
312
            return EAGAIN;
313
            //  10065 - No route to host.
314
        case WSAEHOSTUNREACH:
315
            return EHOSTUNREACH;
316
            //  10066 - Directory not empty.
317
        case WSAENOTEMPTY:
318
            return EFAULT;
319
            //  10067 - Too many processes.
320
        case WSAEPROCLIM:
321
            return EFAULT;
322
            //  10068 - Too many users.
323
        case WSAEUSERS:
324
            return EFAULT;
325
            //  10069 - Disc Quota Exceeded.
326
        case WSAEDQUOT:
327
            return EFAULT;
328
            //  10070 - Stale NFS file handle.
329
        case WSAESTALE:
330
            return EFAULT;
331
            //  10071 - Too many levels of remote in path.
332
        case WSAEREMOTE:
333
            return EFAULT;
334
            //  10091 - Network SubSystem is unavailable.
335
        case WSASYSNOTREADY:
336
            return EFAULT;
337
            //  10092 - WINSOCK DLL Version out of range.
338
        case WSAVERNOTSUPPORTED:
339
            return EFAULT;
340
            //  10093 - Successful WSASTARTUP not yet performed.
341
        case WSANOTINITIALISED:
342
            return EFAULT;
343
            //  11001 - Host not found.
344
        case WSAHOST_NOT_FOUND:
345
            return EFAULT;
346
            //  11002 - Non-Authoritative Host not found.
347
        case WSATRY_AGAIN:
348
            return EFAULT;
349
            //  11003 - Non-Recoverable errors: FORMERR REFUSED NOTIMP.
350
        case WSANO_RECOVERY:
351
            return EFAULT;
352
            //  11004 - Valid name no data record of requested.
353
        case WSANO_DATA:
354
            return EFAULT;
355
        default:
356
            wsa_assert (false);
357
    }
358
    //  Not reachable
359
    return 0;
360
}
361
362
#endif
363
364
#if defined(HAVE_LIBUNWIND) && !defined(__SUNPRO_CC)
365
366
#define UNW_LOCAL_ONLY
367
#include <libunwind.h>
368
#include <dlfcn.h>
369
#include <cxxabi.h>
370
#include "mutex.hpp"
371
372
void zmq::print_backtrace (void)
373
{
374
    static zmq::mutex_t mtx;
375
    mtx.lock ();
376
    Dl_info dl_info;
377
    unw_cursor_t cursor;
378
    unw_context_t ctx;
379
    unsigned frame_n = 0;
380
381
    unw_getcontext (&ctx);
382
    unw_init_local (&cursor, &ctx);
383
384
    while (unw_step (&cursor) > 0) {
385
        unw_word_t offset;
386
        unw_proc_info_t p_info;
387
        static const char unknown[] = "?";
388
        const char *file_name;
389
        char *demangled_name;
390
        char func_name[256] = "";
391
        void *addr;
392
        int rc;
393
394
        if (unw_get_proc_info (&cursor, &p_info))
395
            break;
396
397
        rc = unw_get_proc_name (&cursor, func_name, 256, &offset);
398
        if (rc == -UNW_ENOINFO)
399
            memcpy (func_name, unknown, sizeof unknown);
400
401
        addr = (void *) (p_info.start_ip + offset);
402
403
        if (dladdr (addr, &dl_info) && dl_info.dli_fname)
404
            file_name = dl_info.dli_fname;
405
        else
406
            file_name = unknown;
407
408
        demangled_name = abi::__cxa_demangle (func_name, NULL, NULL, &rc);
409
410
        printf ("#%u  %p in %s (%s+0x%lx)\n", frame_n++, addr, file_name,
411
                rc ? func_name : demangled_name, (unsigned long) offset);
412
        free (demangled_name);
413
    }
414
    puts ("");
415
416
    fflush (stdout);
417
    mtx.unlock ();
418
}
419
420
#else
421
422
void zmq::print_backtrace ()
423
0
{
424
0
}
425
426
#endif