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