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 |