16ff6d951SJohn Birrell /* 26ff6d951SJohn Birrell * CDDL HEADER START 36ff6d951SJohn Birrell * 46ff6d951SJohn Birrell * The contents of this file are subject to the terms of the 56ff6d951SJohn Birrell * Common Development and Distribution License (the "License"). 66ff6d951SJohn Birrell * You may not use this file except in compliance with the License. 76ff6d951SJohn Birrell * 86ff6d951SJohn Birrell * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 96ff6d951SJohn Birrell * or http://www.opensolaris.org/os/licensing. 106ff6d951SJohn Birrell * See the License for the specific language governing permissions 116ff6d951SJohn Birrell * and limitations under the License. 126ff6d951SJohn Birrell * 136ff6d951SJohn Birrell * When distributing Covered Code, include this CDDL HEADER in each 146ff6d951SJohn Birrell * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 156ff6d951SJohn Birrell * If applicable, add the following below this CDDL HEADER, with the 166ff6d951SJohn Birrell * fields enclosed by brackets "[]" replaced with your own identifying 176ff6d951SJohn Birrell * information: Portions Copyright [yyyy] [name of copyright owner] 186ff6d951SJohn Birrell * 196ff6d951SJohn Birrell * CDDL HEADER END 206ff6d951SJohn Birrell */ 21a98ff317SPedro F. Giffuni 226ff6d951SJohn Birrell /* 231670a1c2SRui Paulo * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 246ff6d951SJohn Birrell * Use is subject to license terms. 256ff6d951SJohn Birrell */ 266ff6d951SJohn Birrell 27ba6cafe2SMark Johnston /* 28ba6cafe2SMark Johnston * Copyright (c) 2012 by Delphix. All rights reserved. 2923e4da43SPedro F. Giffuni * Copyright (c) 2013, Joyent, Inc. All rights reserved. 30ba6cafe2SMark Johnston */ 31ba6cafe2SMark Johnston 32768c574fSJohn Birrell #include <string.h> 336ff6d951SJohn Birrell #include <strings.h> 346ff6d951SJohn Birrell #include <dt_impl.h> 356ff6d951SJohn Birrell 366ff6d951SJohn Birrell static const struct { 376ff6d951SJohn Birrell int err; 386ff6d951SJohn Birrell const char *msg; 396ff6d951SJohn Birrell } _dt_errlist[] = { 406ff6d951SJohn Birrell { EDT_VERSION, "Client requested version newer than library" }, 416ff6d951SJohn Birrell { EDT_VERSINVAL, "Version is not properly formatted or is too large" }, 426ff6d951SJohn Birrell { EDT_VERSUNDEF, "Requested version is not supported by compiler" }, 436ff6d951SJohn Birrell { EDT_VERSREDUCED, "Requested version conflicts with earlier setting" }, 446ff6d951SJohn Birrell { EDT_CTF, "Unexpected libctf error" }, 456ff6d951SJohn Birrell { EDT_COMPILER, "Error in D program compilation" }, 466ff6d951SJohn Birrell { EDT_NOTUPREG, "Insufficient tuple registers to generate code" }, 476ff6d951SJohn Birrell { EDT_NOMEM, "Memory allocation failure" }, 486ff6d951SJohn Birrell { EDT_INT2BIG, "Integer constant table limit exceeded" }, 496ff6d951SJohn Birrell { EDT_STR2BIG, "String constant table limit exceeded" }, 506ff6d951SJohn Birrell { EDT_NOMOD, "Unknown module name" }, 516ff6d951SJohn Birrell { EDT_NOPROV, "Unknown provider name" }, 526ff6d951SJohn Birrell { EDT_NOPROBE, "No probe matches description" }, 536ff6d951SJohn Birrell { EDT_NOSYM, "Unknown symbol name" }, 546ff6d951SJohn Birrell { EDT_NOSYMADDR, "No symbol corresponds to address" }, 556ff6d951SJohn Birrell { EDT_NOTYPE, "Unknown type name" }, 566ff6d951SJohn Birrell { EDT_NOVAR, "Unknown variable name" }, 576ff6d951SJohn Birrell { EDT_NOAGG, "Unknown aggregation name" }, 586ff6d951SJohn Birrell { EDT_BADSCOPE, "Improper use of scoping operator in type name" }, 596ff6d951SJohn Birrell { EDT_BADSPEC, "Overspecified probe description" }, 606ff6d951SJohn Birrell { EDT_BADSPCV, "Undefined macro variable in probe description" }, 616ff6d951SJohn Birrell { EDT_BADID, "Unknown probe identifier" }, 626ff6d951SJohn Birrell { EDT_NOTLOADED, "Module is no longer loaded" }, 636ff6d951SJohn Birrell { EDT_NOCTF, "Module does not contain any CTF data" }, 646ff6d951SJohn Birrell { EDT_DATAMODEL, "Module and program data models do not match" }, 656ff6d951SJohn Birrell { EDT_DIFVERS, "Library uses newer DIF version than kernel" }, 666ff6d951SJohn Birrell { EDT_BADAGG, "Unknown aggregating action" }, 676ff6d951SJohn Birrell { EDT_FIO, "Error occurred while reading from input stream" }, 686ff6d951SJohn Birrell { EDT_DIFINVAL, "DIF program content is invalid" }, 696ff6d951SJohn Birrell { EDT_DIFSIZE, "DIF program exceeds maximum program size" }, 706ff6d951SJohn Birrell { EDT_DIFFAULT, "DIF program contains invalid pointer" }, 716ff6d951SJohn Birrell { EDT_BADPROBE, "Invalid probe specification" }, 726ff6d951SJohn Birrell { EDT_BADPGLOB, "Probe description has too many globbing characters" }, 736ff6d951SJohn Birrell { EDT_NOSCOPE, "Declaration scope stack underflow" }, 746ff6d951SJohn Birrell { EDT_NODECL, "Declaration stack underflow" }, 756ff6d951SJohn Birrell { EDT_DMISMATCH, "Data record list does not match statement" }, 766ff6d951SJohn Birrell { EDT_DOFFSET, "Data record offset exceeds buffer boundary" }, 776ff6d951SJohn Birrell { EDT_DALIGN, "Data record has inappropriate alignment" }, 786ff6d951SJohn Birrell { EDT_BADOPTNAME, "Invalid option name" }, 796ff6d951SJohn Birrell { EDT_BADOPTVAL, "Invalid value for specified option" }, 806ff6d951SJohn Birrell { EDT_BADOPTCTX, "Option cannot be used from within a D program" }, 816ff6d951SJohn Birrell { EDT_CPPFORK, "Failed to fork preprocessor" }, 826ff6d951SJohn Birrell { EDT_CPPEXEC, "Failed to exec preprocessor" }, 836ff6d951SJohn Birrell { EDT_CPPENT, "Preprocessor not found" }, 846ff6d951SJohn Birrell { EDT_CPPERR, "Preprocessor failed to process input program" }, 856ff6d951SJohn Birrell { EDT_SYMOFLOW, "Symbol table identifier space exhausted" }, 866ff6d951SJohn Birrell { EDT_ACTIVE, "Operation illegal when tracing is active" }, 876ff6d951SJohn Birrell { EDT_DESTRUCTIVE, "Destructive actions not allowed" }, 886ff6d951SJohn Birrell { EDT_NOANON, "No anonymous tracing state" }, 896ff6d951SJohn Birrell { EDT_ISANON, "Can't claim anonymous state and enable probes" }, 906ff6d951SJohn Birrell { EDT_ENDTOOBIG, "END enablings exceed size of principal buffer" }, 916ff6d951SJohn Birrell { EDT_NOCONV, "Failed to load type for printf conversion" }, 926ff6d951SJohn Birrell { EDT_BADCONV, "Incomplete printf conversion" }, 936ff6d951SJohn Birrell { EDT_BADERROR, "Invalid library ERROR action" }, 946ff6d951SJohn Birrell { EDT_ERRABORT, "Abort due to error" }, 956ff6d951SJohn Birrell { EDT_DROPABORT, "Abort due to drop" }, 966ff6d951SJohn Birrell { EDT_DIRABORT, "Abort explicitly directed" }, 976ff6d951SJohn Birrell { EDT_BADRVAL, "Invalid return value from callback" }, 986ff6d951SJohn Birrell { EDT_BADNORMAL, "Invalid normalization" }, 996ff6d951SJohn Birrell { EDT_BUFTOOSMALL, "Enabling exceeds size of buffer" }, 1006ff6d951SJohn Birrell { EDT_BADTRUNC, "Invalid truncation" }, 1016ff6d951SJohn Birrell { EDT_BUSY, "DTrace cannot be used when kernel debugger is active" }, 1026ff6d951SJohn Birrell { EDT_ACCESS, "DTrace requires additional privileges" }, 1036ff6d951SJohn Birrell { EDT_NOENT, "DTrace device not available on system" }, 1046ff6d951SJohn Birrell { EDT_BRICKED, "Abort due to systemic unresponsiveness" }, 1056ff6d951SJohn Birrell { EDT_HARDWIRE, "Failed to load language definitions" }, 1066ff6d951SJohn Birrell { EDT_ELFVERSION, "libelf is out-of-date with respect to libdtrace" }, 1076ff6d951SJohn Birrell { EDT_NOBUFFERED, "Attempt to buffer output without handler" }, 1086ff6d951SJohn Birrell { EDT_UNSTABLE, "Description matched an unstable set of probes" }, 1096ff6d951SJohn Birrell { EDT_BADSETOPT, "Invalid setopt() library action" }, 1106ff6d951SJohn Birrell { EDT_BADSTACKPC, "Invalid stack program counter size" }, 1116ff6d951SJohn Birrell { EDT_BADAGGVAR, "Invalid aggregation variable identifier" }, 1121670a1c2SRui Paulo { EDT_OVERSION, "Client requested deprecated version of library" }, 11323e4da43SPedro F. Giffuni { EDT_ENABLING_ERR, "Failed to enable probe" }, 11423e4da43SPedro F. Giffuni { EDT_NOPROBES, "No probe sites found for declared provider" } 1156ff6d951SJohn Birrell }; 1166ff6d951SJohn Birrell 1176ff6d951SJohn Birrell static const int _dt_nerr = sizeof (_dt_errlist) / sizeof (_dt_errlist[0]); 1186ff6d951SJohn Birrell 1196ff6d951SJohn Birrell const char * 1206ff6d951SJohn Birrell dtrace_errmsg(dtrace_hdl_t *dtp, int error) 1216ff6d951SJohn Birrell { 1226ff6d951SJohn Birrell const char *str; 1236ff6d951SJohn Birrell int i; 1246ff6d951SJohn Birrell 1256ff6d951SJohn Birrell if (error == EDT_COMPILER && dtp != NULL && dtp->dt_errmsg[0] != '\0') 1266ff6d951SJohn Birrell str = dtp->dt_errmsg; 1276ff6d951SJohn Birrell else if (error == EDT_CTF && dtp != NULL && dtp->dt_ctferr != 0) 1286ff6d951SJohn Birrell str = ctf_errmsg(dtp->dt_ctferr); 1296ff6d951SJohn Birrell else if (error >= EDT_BASE && (error - EDT_BASE) < _dt_nerr) { 1306ff6d951SJohn Birrell for (i = 0; i < _dt_nerr; i++) { 1316ff6d951SJohn Birrell if (_dt_errlist[i].err == error) 1326ff6d951SJohn Birrell return (_dt_errlist[i].msg); 1336ff6d951SJohn Birrell } 1346ff6d951SJohn Birrell str = NULL; 1356ff6d951SJohn Birrell } else 1366ff6d951SJohn Birrell str = strerror(error); 1376ff6d951SJohn Birrell 1386ff6d951SJohn Birrell return (str ? str : "Unknown error"); 1396ff6d951SJohn Birrell } 1406ff6d951SJohn Birrell 1416ff6d951SJohn Birrell int 1426ff6d951SJohn Birrell dtrace_errno(dtrace_hdl_t *dtp) 1436ff6d951SJohn Birrell { 1446ff6d951SJohn Birrell return (dtp->dt_errno); 1456ff6d951SJohn Birrell } 1466ff6d951SJohn Birrell 147768c574fSJohn Birrell #if defined(sun) 1486ff6d951SJohn Birrell int 1496ff6d951SJohn Birrell dt_set_errno(dtrace_hdl_t *dtp, int err) 1506ff6d951SJohn Birrell { 1516ff6d951SJohn Birrell dtp->dt_errno = err; 1526ff6d951SJohn Birrell return (-1); 1536ff6d951SJohn Birrell } 154768c574fSJohn Birrell #else 155768c574fSJohn Birrell int 156768c574fSJohn Birrell _dt_set_errno(dtrace_hdl_t *dtp, int err, const char *errfile, int errline) 157768c574fSJohn Birrell { 158768c574fSJohn Birrell dtp->dt_errno = err; 159768c574fSJohn Birrell dtp->dt_errfile = errfile; 160768c574fSJohn Birrell dtp->dt_errline = errline; 161768c574fSJohn Birrell return (-1); 162768c574fSJohn Birrell } 163768c574fSJohn Birrell 164768c574fSJohn Birrell void dt_get_errloc(dtrace_hdl_t *dtp, const char **p_errfile, int *p_errline) 165768c574fSJohn Birrell { 166768c574fSJohn Birrell *p_errfile = dtp->dt_errfile; 167768c574fSJohn Birrell *p_errline = dtp->dt_errline; 168768c574fSJohn Birrell } 169768c574fSJohn Birrell #endif 1706ff6d951SJohn Birrell 1716ff6d951SJohn Birrell void 1726ff6d951SJohn Birrell dt_set_errmsg(dtrace_hdl_t *dtp, const char *errtag, const char *region, 1736ff6d951SJohn Birrell const char *filename, int lineno, const char *format, va_list ap) 1746ff6d951SJohn Birrell { 1756ff6d951SJohn Birrell size_t len, n; 1766ff6d951SJohn Birrell char *p, *s; 1776ff6d951SJohn Birrell 1786ff6d951SJohn Birrell s = dtp->dt_errmsg; 1796ff6d951SJohn Birrell n = sizeof (dtp->dt_errmsg); 1806ff6d951SJohn Birrell 1816ff6d951SJohn Birrell if (errtag != NULL && (yypcb->pcb_cflags & DTRACE_C_ETAGS)) 1826ff6d951SJohn Birrell (void) snprintf(s, n, "[%s] ", errtag); 1836ff6d951SJohn Birrell else 1846ff6d951SJohn Birrell s[0] = '\0'; 1856ff6d951SJohn Birrell 1866ff6d951SJohn Birrell len = strlen(dtp->dt_errmsg); 1876ff6d951SJohn Birrell s = dtp->dt_errmsg + len; 1886ff6d951SJohn Birrell n = sizeof (dtp->dt_errmsg) - len; 1896ff6d951SJohn Birrell 1906ff6d951SJohn Birrell if (filename == NULL) 1916ff6d951SJohn Birrell filename = dtp->dt_filetag; 1926ff6d951SJohn Birrell 1936ff6d951SJohn Birrell if (filename != NULL) 1946ff6d951SJohn Birrell (void) snprintf(s, n, "\"%s\", line %d: ", filename, lineno); 1956ff6d951SJohn Birrell else if (lineno != 0) 1966ff6d951SJohn Birrell (void) snprintf(s, n, "line %d: ", lineno); 1976ff6d951SJohn Birrell else if (region != NULL) 1986ff6d951SJohn Birrell (void) snprintf(s, n, "in %s: ", region); 1996ff6d951SJohn Birrell 2006ff6d951SJohn Birrell len = strlen(dtp->dt_errmsg); 2016ff6d951SJohn Birrell s = dtp->dt_errmsg + len; 2026ff6d951SJohn Birrell n = sizeof (dtp->dt_errmsg) - len; 2036ff6d951SJohn Birrell (void) vsnprintf(s, n, format, ap); 2046ff6d951SJohn Birrell 2056ff6d951SJohn Birrell if ((p = strrchr(dtp->dt_errmsg, '\n')) != NULL) 2066ff6d951SJohn Birrell *p = '\0'; /* remove trailing \n from message buffer */ 2076ff6d951SJohn Birrell 2086ff6d951SJohn Birrell dtp->dt_errtag = errtag; 2096ff6d951SJohn Birrell } 2106ff6d951SJohn Birrell 2116ff6d951SJohn Birrell /*ARGSUSED*/ 2126ff6d951SJohn Birrell const char * 2136ff6d951SJohn Birrell dtrace_faultstr(dtrace_hdl_t *dtp, int fault) 2146ff6d951SJohn Birrell { 2156ff6d951SJohn Birrell int i; 2166ff6d951SJohn Birrell 2176ff6d951SJohn Birrell static const struct { 2186ff6d951SJohn Birrell int code; 2196ff6d951SJohn Birrell const char *str; 2206ff6d951SJohn Birrell } faults[] = { 2216ff6d951SJohn Birrell { DTRACEFLT_BADADDR, "invalid address" }, 2226ff6d951SJohn Birrell { DTRACEFLT_BADALIGN, "invalid alignment" }, 2236ff6d951SJohn Birrell { DTRACEFLT_ILLOP, "illegal operation" }, 2246ff6d951SJohn Birrell { DTRACEFLT_DIVZERO, "divide-by-zero" }, 2256ff6d951SJohn Birrell { DTRACEFLT_NOSCRATCH, "out of scratch space" }, 2266ff6d951SJohn Birrell { DTRACEFLT_KPRIV, "invalid kernel access" }, 2276ff6d951SJohn Birrell { DTRACEFLT_UPRIV, "invalid user access" }, 2286ff6d951SJohn Birrell { DTRACEFLT_TUPOFLOW, "tuple stack overflow" }, 2296ff6d951SJohn Birrell { DTRACEFLT_BADSTACK, "bad stack" }, 2306ff6d951SJohn Birrell { DTRACEFLT_LIBRARY, "library-level fault" }, 2316ff6d951SJohn Birrell { 0, NULL } 2326ff6d951SJohn Birrell }; 2336ff6d951SJohn Birrell 2346ff6d951SJohn Birrell for (i = 0; faults[i].str != NULL; i++) { 2356ff6d951SJohn Birrell if (faults[i].code == fault) 2366ff6d951SJohn Birrell return (faults[i].str); 2376ff6d951SJohn Birrell } 2386ff6d951SJohn Birrell 2396ff6d951SJohn Birrell return ("unknown fault"); 2406ff6d951SJohn Birrell } 241