xref: /illumos-gate/usr/src/cmd/mdb/common/mdb/mdb_err.c (revision 0b453801)
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 #include <mdb/mdb_signal.h>
28 #include <mdb/mdb_err.h>
29 #include <mdb/mdb.h>
30 
31 #include <thread_db.h>
32 #include <rtld_db.h>
33 #include <libctf.h>
34 #include <strings.h>
35 #include <stdlib.h>
36 
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 
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 *
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
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
176 vdie(const char *format, va_list alist)
177 {
178 	vwarn(format, alist);
179 	mdb_destroy();
180 	exit(1);
181 }
182 
183 void
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
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
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
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
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
258 set_errno(int err)
259 {
260 	errno = err;
261 	return (-1);
262 }
263 
264 int
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
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
315 rdb_to_errno(int err)
316 {
317 	errno_rtld_db = err;
318 	return (EMDB_RTLD_DB);
319 }
320 #endif /* _KMDB */
321