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 
errno_to_string(int errno_)34 const 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 
zmq_abort(const char * errmsg_)77 void 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 
wsa_error()94 const char *zmq::wsa_error ()
95 {
96     return wsa_error_no (WSAGetLastError (), NULL);
97 }
98 
wsa_error_no(int no_,const char * wsae_wouldblock_string_)99 const 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 
win_error(char * buffer_,size_t buffer_size_)212 void zmq::win_error (char *buffer_, size_t buffer_size_)
213 {
214     const 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     const 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 
wsa_error_to_errno(int errcode_)229 int 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 
print_backtrace(void)399 void 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         static const char unknown[] = "?";
415         const char *file_name;
416         char *demangled_name;
417         char func_name[256] = "";
418         void *addr;
419         int rc;
420 
421         if (unw_get_proc_info (&cursor, &p_info))
422             break;
423 
424         rc = unw_get_proc_name (&cursor, func_name, 256, &offset);
425         if (rc == -UNW_ENOINFO)
426             memcpy (func_name, unknown, sizeof unknown);
427 
428         addr = (void *) (p_info.start_ip + offset);
429 
430         if (dladdr (addr, &dl_info) && dl_info.dli_fname)
431             file_name = dl_info.dli_fname;
432         else
433             file_name = unknown;
434 
435         demangled_name = abi::__cxa_demangle (func_name, NULL, NULL, &rc);
436 
437         printf ("#%u  %p in %s (%s+0x%lx)\n", frame_n++, addr, file_name,
438                 rc ? func_name : demangled_name, (unsigned long) offset);
439         free (demangled_name);
440     }
441     puts ("");
442 
443     fflush (stdout);
444     mtx.unlock ();
445 }
446 
447 #else
448 
print_backtrace()449 void zmq::print_backtrace ()
450 {
451 }
452 
453 #endif
454