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