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 "unexpected short write" /* EMDB_SHORTWRITE */ 118 119 }; 120 121 static const int _mdb_nerr = sizeof (_mdb_errlist) / sizeof (_mdb_errlist[0]); 122 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 129 130 const char * 131 mdb_strerror(int err) 132 { 133 static char buf[256]; 134 const char *str; 135 136 if (err >= EMDB_BASE && (err - EMDB_BASE) < _mdb_nerr) 137 str = _mdb_errlist[err - EMDB_BASE]; 138 else 139 str = strerror(err); 140 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; 147 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 154 155 case EMDB_CTF: 156 if (ctf_errmsg(errno_libctf) != NULL) 157 str = ctf_errmsg(errno_libctf); 158 break; 159 } 160 161 return (str ? str : "unknown error"); 162 } 163 164 void 165 vwarn(const char *format, va_list alist) 166 { 167 int err = errno; 168 169 mdb_iob_printf(mdb.m_err, "%s: ", mdb.m_pname); 170 mdb_iob_vprintf(mdb.m_err, format, alist); 171 172 if (strchr(format, '\n') == NULL) 173 mdb_iob_printf(mdb.m_err, ": %s\n", mdb_strerror(err)); 174 } 175 176 void 177 vdie(const char *format, va_list alist) 178 { 179 vwarn(format, alist); 180 mdb_destroy(); 181 exit(1); 182 } 183 184 void 185 vfail(const char *format, va_list alist) 186 { 187 extern const char *volatile _mdb_abort_str; 188 static char buf[256]; 189 static int nfail; 190 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); 194 195 nfail = 1; 196 } 197 198 /* 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. 202 */ 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); 207 208 (void) mdb_signal_blockall(); 209 (void) mdb_signal_raise(SIGABRT); 210 (void) mdb_signal_unblock(SIGABRT); 211 } 212 213 exit(1); 214 } 215 216 /*PRINTFLIKE1*/ 217 void 218 warn(const char *format, ...) 219 { 220 va_list alist; 221 222 va_start(alist, format); 223 vwarn(format, alist); 224 va_end(alist); 225 } 226 227 /*PRINTFLIKE1*/ 228 void 229 die(const char *format, ...) 230 { 231 va_list alist; 232 233 va_start(alist, format); 234 vdie(format, alist); 235 va_end(alist); 236 } 237 238 /*PRINTFLIKE1*/ 239 void 240 fail(const char *format, ...) 241 { 242 va_list alist; 243 244 va_start(alist, format); 245 vfail(format, alist); 246 va_end(alist); 247 } 248 249 int 250 set_errbytes(size_t rbytes, size_t nbytes) 251 { 252 errno_rbytes = rbytes; 253 errno_nbytes = nbytes; 254 errno = EMDB_PARTIAL; 255 return (-1); 256 } 257 258 int 259 set_errno(int err) 260 { 261 errno = err; 262 return (-1); 263 } 264 265 int 266 ctf_to_errno(int err) 267 { 268 errno_libctf = err; 269 return (EMDB_CTF); 270 } 271 272 #ifndef _KMDB 273 /* 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. 280 */ 281 int 282 tdb_to_errno(int err) 283 { 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); 312 } 313 } 314 315 int 316 rdb_to_errno(int err) 317 { 318 errno_rtld_db = err; 319 return (EMDB_RTLD_DB); 320 } 321 #endif /* _KMDB */ 322