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