1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <mdb/mdb_signal.h>
30 #include <mdb/mdb_err.h>
31 #include <mdb/mdb.h>
32
33 #include <thread_db.h>
34 #include <rtld_db.h>
35 #include <libctf.h>
36 #include <strings.h>
37 #include <stdlib.h>
38
39 static const char *const _mdb_errlist[] = {
40 "unknown symbol name", /* EMDB_NOSYM */
41 "unknown object file name", /* EMDB_NOOBJ */
42 "no mapping for address", /* EMDB_NOMAP */
43 "unknown dcmd name", /* EMDB_NODCMD */
44 "unknown walk name", /* EMDB_NOWALK */
45 "dcmd name already in use", /* EMDB_DCMDEXISTS */
46 "walk name already in use", /* EMDB_WALKEXISTS */
47 "no support for platform", /* EMDB_NOPLAT */
48 "no process active", /* EMDB_NOPROC */
49 "specified name is too long", /* EMDB_NAME2BIG */
50 "specified name contains illegal characters", /* EMDB_NAMEBAD */
51 "failed to allocate needed memory", /* EMDB_ALLOC */
52 "specified module is not loaded", /* EMDB_NOMOD */
53 "cannot unload built-in module", /* EMDB_BUILTINMOD */
54 "no walk is currently active", /* EMDB_NOWCB */
55 "invalid walk state argument", /* EMDB_BADWCB */
56 "walker does not accept starting address", /* EMDB_NOWALKLOC */
57 "walker requires starting address", /* EMDB_NOWALKGLOB */
58 "failed to initialize walk", /* EMDB_WALKINIT */
59 "walker cannot be layered on itself", /* EMDB_WALKLOOP */
60 "i/o stream is read-only", /* EMDB_IORO */
61 "i/o stream is write-only", /* EMDB_IOWO */
62 "no symbol corresponds to address", /* EMDB_NOSYMADDR */
63 "unknown disassembler name", /* EMDB_NODIS */
64 "disassembler name already in use", /* EMDB_DISEXISTS */
65 "no such software event specifier", /* EMDB_NOSESPEC */
66 "no such xdata available", /* EMDB_NOXD */
67 "xdata name already in use", /* EMDB_XDEXISTS */
68 "operation not supported by target", /* EMDB_TGTNOTSUP */
69 "target is not open for writing", /* EMDB_TGTRDONLY */
70 "invalid register name", /* EMDB_BADREG */
71 "no register set available for thread", /* EMDB_NOREGS */
72 "stack address is not properly aligned", /* EMDB_STKALIGN */
73 "no executable file is open", /* EMDB_NOEXEC */
74 "failed to evaluate command", /* EMDB_EVAL */
75 "command cancelled by user", /* EMDB_CANCEL */
76 "only %lu of %lu bytes could be read", /* EMDB_PARTIAL */
77 "dcmd failed", /* EMDB_DCFAIL */
78 "improper dcmd usage", /* EMDB_DCUSAGE */
79 "target error", /* EMDB_TGT */
80 "invalid system call number", /* EMDB_BADSYSNUM */
81 "invalid signal number", /* EMDB_BADSIGNUM */
82 "invalid fault number", /* EMDB_BADFLTNUM */
83 "target is currently executing", /* EMDB_TGTBUSY */
84 "target has completed execution", /* EMDB_TGTZOMB */
85 "target is a core file", /* EMDB_TGTCORE */
86 "debugger lost control of target", /* EMDB_TGTLOST */
87 "libthread_db call failed unexpectedly", /* EMDB_TDB */
88 "failed to dlopen library", /* EMDB_RTLD */
89 "librtld_db call failed unexpectedly", /* EMDB_RTLD_DB */
90 "runtime linker data not available", /* EMDB_NORTLD */
91 "invalid thread identifier", /* EMDB_NOTHREAD */
92 "event specifier disabled", /* EMDB_SPECDIS */
93 "unknown link map id", /* EMDB_NOLMID */
94 "failed to determine return address", /* EMDB_NORETADDR */
95 "watchpoint size exceeds address space limit", /* EMDB_WPRANGE */
96 "conflict with existing watchpoint", /* EMDB_WPDUP */
97 "address not aligned on an instruction boundary", /* EMDB_BPALIGN */
98 "library is missing demangler entry point", /* EMDB_NODEM */
99 "cannot read past current end of file", /* EMDB_EOF */
100 "no symbolic debug information available for module", /* EMDB_NOCTF */
101 "libctf call failed unexpectedly", /* EMDB_CTF */
102 "thread local storage has not yet been allocated", /* EMDB_TLS */
103 "object does not support thread local storage", /* EMDB_NOTLS */
104 "no such member of structure or union", /* EMDB_CTFNOMEMB */
105 "inappropriate context for action", /* EMDB_CTX */
106 "module incompatible with target", /* EMDB_INCOMPAT */
107 "operation not supported by target on this platform",
108 /* EMDB_TGTHWNOTSUP */
109 "kmdb is not loaded", /* EMDB_KINACTIVE */
110 "kmdb is loading", /* EMDB_KACTIVATING */
111 "kmdb is already loaded", /* EMDB_KACTIVE */
112 "kmdb is unloading", /* EMDB_KDEACTIVATING */
113 "kmdb could not be loaded", /* EMDB_KNOLOAD */
114 "boot-loaded kmdb cannot be unloaded", /* EMDB_KNOUNLOAD */
115 "too many enabled watchpoints for this machine", /* EMDB_WPTOOMANY */
116 "DTrace is active", /* EMDB_DTACTIVE */
117 "boot-loaded module cannot be unloaded" /* EMDB_KMODNOUNLOAD */
118 };
119
120 static const int _mdb_nerr = sizeof (_mdb_errlist) / sizeof (_mdb_errlist[0]);
121
122 static size_t errno_rbytes; /* EMDB_PARTIAL actual bytes read */
123 static size_t errno_nbytes; /* EMDB_PARTIAL total bytes requested */
124 static int errno_libctf; /* EMDB_CTF underlying error code */
125 #ifndef _KMDB
126 static int errno_rtld_db; /* EMDB_RTLD_DB underlying error code */
127 #endif
128
129 const char *
mdb_strerror(int err)130 mdb_strerror(int err)
131 {
132 static char buf[256];
133 const char *str;
134
135 if (err >= EMDB_BASE && (err - EMDB_BASE) < _mdb_nerr)
136 str = _mdb_errlist[err - EMDB_BASE];
137 else
138 str = strerror(err);
139
140 switch (err) {
141 case EMDB_PARTIAL:
142 (void) mdb_iob_snprintf(buf, sizeof (buf), str,
143 errno_rbytes, errno_nbytes);
144 str = buf;
145 break;
146
147 #ifndef _KMDB
148 case EMDB_RTLD_DB:
149 if (rd_errstr(errno_rtld_db) != NULL)
150 str = rd_errstr(errno_rtld_db);
151 break;
152 #endif
153
154 case EMDB_CTF:
155 if (ctf_errmsg(errno_libctf) != NULL)
156 str = ctf_errmsg(errno_libctf);
157 break;
158 }
159
160 return (str ? str : "unknown error");
161 }
162
163 void
vwarn(const char * format,va_list alist)164 vwarn(const char *format, va_list alist)
165 {
166 int err = errno;
167
168 mdb_iob_printf(mdb.m_err, "%s: ", mdb.m_pname);
169 mdb_iob_vprintf(mdb.m_err, format, alist);
170
171 if (strchr(format, '\n') == NULL)
172 mdb_iob_printf(mdb.m_err, ": %s\n", mdb_strerror(err));
173 }
174
175 void
vdie(const char * format,va_list alist)176 vdie(const char *format, va_list alist)
177 {
178 vwarn(format, alist);
179 mdb_destroy();
180 exit(1);
181 }
182
183 void
vfail(const char * format,va_list alist)184 vfail(const char *format, va_list alist)
185 {
186 extern const char *volatile _mdb_abort_str;
187 static char buf[256];
188 static int nfail;
189
190 if (_mdb_abort_str == NULL) {
191 _mdb_abort_str = buf; /* Do this first so we don't recurse */
192 (void) mdb_iob_vsnprintf(buf, sizeof (buf), format, alist);
193
194 nfail = 1;
195 }
196
197 /*
198 * We'll try to print failure messages twice. Any more than that,
199 * and we're probably hitting an assertion or some other problem in
200 * the printing routines, and will recurse until we run out of stack.
201 */
202 if (nfail++ < 3) {
203 mdb_iob_printf(mdb.m_err, "%s ABORT: ", mdb.m_pname);
204 mdb_iob_vprintf(mdb.m_err, format, alist);
205 mdb_iob_flush(mdb.m_err);
206
207 (void) mdb_signal_blockall();
208 (void) mdb_signal_raise(SIGABRT);
209 (void) mdb_signal_unblock(SIGABRT);
210 }
211
212 exit(1);
213 }
214
215 /*PRINTFLIKE1*/
216 void
warn(const char * format,...)217 warn(const char *format, ...)
218 {
219 va_list alist;
220
221 va_start(alist, format);
222 vwarn(format, alist);
223 va_end(alist);
224 }
225
226 /*PRINTFLIKE1*/
227 void
die(const char * format,...)228 die(const char *format, ...)
229 {
230 va_list alist;
231
232 va_start(alist, format);
233 vdie(format, alist);
234 va_end(alist);
235 }
236
237 /*PRINTFLIKE1*/
238 void
fail(const char * format,...)239 fail(const char *format, ...)
240 {
241 va_list alist;
242
243 va_start(alist, format);
244 vfail(format, alist);
245 va_end(alist);
246 }
247
248 int
set_errbytes(size_t rbytes,size_t nbytes)249 set_errbytes(size_t rbytes, size_t nbytes)
250 {
251 errno_rbytes = rbytes;
252 errno_nbytes = nbytes;
253 errno = EMDB_PARTIAL;
254 return (-1);
255 }
256
257 int
set_errno(int err)258 set_errno(int err)
259 {
260 errno = err;
261 return (-1);
262 }
263
264 int
ctf_to_errno(int err)265 ctf_to_errno(int err)
266 {
267 errno_libctf = err;
268 return (EMDB_CTF);
269 }
270
271 #ifndef _KMDB
272 /*
273 * The libthread_db interface is a superfund site and provides no strerror
274 * equivalent for us to call: we try to provide some sensible handling for its
275 * garbage bin of error return codes here. First of all, we don't bother
276 * interpreting all of the possibilities, since many of them aren't even used
277 * in the implementation anymore. We try to map thread_db errors we may see
278 * to UNIX errnos or mdb errnos as appropriate.
279 */
280 int
tdb_to_errno(int err)281 tdb_to_errno(int err)
282 {
283 switch (err) {
284 case TD_OK:
285 case TD_PARTIALREG:
286 return (0);
287 case TD_NOCAPAB:
288 return (ENOTSUP);
289 case TD_BADPH:
290 case TD_BADTH:
291 case TD_BADSH:
292 case TD_BADTA:
293 case TD_BADKEY:
294 case TD_NOEVENT:
295 return (EINVAL);
296 case TD_NOFPREGS:
297 case TD_NOXREGS:
298 return (EMDB_NOREGS);
299 case TD_NOTHR:
300 return (EMDB_NOTHREAD);
301 case TD_MALLOC:
302 return (EMDB_ALLOC);
303 case TD_TLSDEFER:
304 return (EMDB_TLS);
305 case TD_NOTLS:
306 return (EMDB_NOTLS);
307 case TD_DBERR:
308 case TD_ERR:
309 default:
310 return (EMDB_TDB);
311 }
312 }
313
314 int
rdb_to_errno(int err)315 rdb_to_errno(int err)
316 {
317 errno_rtld_db = err;
318 return (EMDB_RTLD_DB);
319 }
320 #endif /* _KMDB */
321