1a864dc36Sdarran /*
2a864dc36Sdarran * CDDL HEADER START
3a864dc36Sdarran *
4a864dc36Sdarran * The contents of this file are subject to the terms of the
5a864dc36Sdarran * Common Development and Distribution License (the "License").
6a864dc36Sdarran * You may not use this file except in compliance with the License.
7a864dc36Sdarran *
8a864dc36Sdarran * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9a864dc36Sdarran * or http://www.opensolaris.org/os/licensing.
10a864dc36Sdarran * See the License for the specific language governing permissions
11a864dc36Sdarran * and limitations under the License.
12a864dc36Sdarran *
13a864dc36Sdarran * When distributing Covered Code, include this CDDL HEADER in each
14a864dc36Sdarran * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15a864dc36Sdarran * If applicable, add the following below this CDDL HEADER, with the
16a864dc36Sdarran * fields enclosed by brackets "[]" replaced with your own identifying
17a864dc36Sdarran * information: Portions Copyright [yyyy] [name of copyright owner]
18a864dc36Sdarran *
19a864dc36Sdarran * CDDL HEADER END
20a864dc36Sdarran */
21*920211a7Schristos
22a864dc36Sdarran /*
23a252d550Shaad * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24a864dc36Sdarran * Use is subject to license terms.
25a864dc36Sdarran */
26a864dc36Sdarran
27*920211a7Schristos /*
28*920211a7Schristos * Copyright (c) 2012 by Delphix. All rights reserved.
29*920211a7Schristos * Copyright (c) 2013, Joyent, Inc. All rights reserved.
30*920211a7Schristos */
31*920211a7Schristos
32*920211a7Schristos #include <string.h>
33a864dc36Sdarran #include <strings.h>
34a864dc36Sdarran #include <dt_impl.h>
35a864dc36Sdarran
36a864dc36Sdarran static const struct {
37a864dc36Sdarran int err;
38a864dc36Sdarran const char *msg;
39a864dc36Sdarran } _dt_errlist[] = {
40a864dc36Sdarran { EDT_VERSION, "Client requested version newer than library" },
41a864dc36Sdarran { EDT_VERSINVAL, "Version is not properly formatted or is too large" },
42a864dc36Sdarran { EDT_VERSUNDEF, "Requested version is not supported by compiler" },
43a864dc36Sdarran { EDT_VERSREDUCED, "Requested version conflicts with earlier setting" },
44a864dc36Sdarran { EDT_CTF, "Unexpected libctf error" },
45a864dc36Sdarran { EDT_COMPILER, "Error in D program compilation" },
46a864dc36Sdarran { EDT_NOTUPREG, "Insufficient tuple registers to generate code" },
47a864dc36Sdarran { EDT_NOMEM, "Memory allocation failure" },
48a864dc36Sdarran { EDT_INT2BIG, "Integer constant table limit exceeded" },
49a864dc36Sdarran { EDT_STR2BIG, "String constant table limit exceeded" },
50a864dc36Sdarran { EDT_NOMOD, "Unknown module name" },
51a864dc36Sdarran { EDT_NOPROV, "Unknown provider name" },
52a864dc36Sdarran { EDT_NOPROBE, "No probe matches description" },
53a864dc36Sdarran { EDT_NOSYM, "Unknown symbol name" },
54a864dc36Sdarran { EDT_NOSYMADDR, "No symbol corresponds to address" },
55a864dc36Sdarran { EDT_NOTYPE, "Unknown type name" },
56a864dc36Sdarran { EDT_NOVAR, "Unknown variable name" },
57a864dc36Sdarran { EDT_NOAGG, "Unknown aggregation name" },
58a864dc36Sdarran { EDT_BADSCOPE, "Improper use of scoping operator in type name" },
59a864dc36Sdarran { EDT_BADSPEC, "Overspecified probe description" },
60a864dc36Sdarran { EDT_BADSPCV, "Undefined macro variable in probe description" },
61a864dc36Sdarran { EDT_BADID, "Unknown probe identifier" },
62a864dc36Sdarran { EDT_NOTLOADED, "Module is no longer loaded" },
63a864dc36Sdarran { EDT_NOCTF, "Module does not contain any CTF data" },
64a864dc36Sdarran { EDT_DATAMODEL, "Module and program data models do not match" },
65a864dc36Sdarran { EDT_DIFVERS, "Library uses newer DIF version than kernel" },
66a864dc36Sdarran { EDT_BADAGG, "Unknown aggregating action" },
67a864dc36Sdarran { EDT_FIO, "Error occurred while reading from input stream" },
68a864dc36Sdarran { EDT_DIFINVAL, "DIF program content is invalid" },
69a864dc36Sdarran { EDT_DIFSIZE, "DIF program exceeds maximum program size" },
70a864dc36Sdarran { EDT_DIFFAULT, "DIF program contains invalid pointer" },
71a864dc36Sdarran { EDT_BADPROBE, "Invalid probe specification" },
72a864dc36Sdarran { EDT_BADPGLOB, "Probe description has too many globbing characters" },
73a864dc36Sdarran { EDT_NOSCOPE, "Declaration scope stack underflow" },
74a864dc36Sdarran { EDT_NODECL, "Declaration stack underflow" },
75a864dc36Sdarran { EDT_DMISMATCH, "Data record list does not match statement" },
76a864dc36Sdarran { EDT_DOFFSET, "Data record offset exceeds buffer boundary" },
77a864dc36Sdarran { EDT_DALIGN, "Data record has inappropriate alignment" },
78a864dc36Sdarran { EDT_BADOPTNAME, "Invalid option name" },
79a864dc36Sdarran { EDT_BADOPTVAL, "Invalid value for specified option" },
80a864dc36Sdarran { EDT_BADOPTCTX, "Option cannot be used from within a D program" },
81a864dc36Sdarran { EDT_CPPFORK, "Failed to fork preprocessor" },
82a864dc36Sdarran { EDT_CPPEXEC, "Failed to exec preprocessor" },
83a864dc36Sdarran { EDT_CPPENT, "Preprocessor not found" },
84a864dc36Sdarran { EDT_CPPERR, "Preprocessor failed to process input program" },
85a864dc36Sdarran { EDT_SYMOFLOW, "Symbol table identifier space exhausted" },
86a864dc36Sdarran { EDT_ACTIVE, "Operation illegal when tracing is active" },
87a864dc36Sdarran { EDT_DESTRUCTIVE, "Destructive actions not allowed" },
88a864dc36Sdarran { EDT_NOANON, "No anonymous tracing state" },
89a864dc36Sdarran { EDT_ISANON, "Can't claim anonymous state and enable probes" },
90a864dc36Sdarran { EDT_ENDTOOBIG, "END enablings exceed size of principal buffer" },
91a864dc36Sdarran { EDT_NOCONV, "Failed to load type for printf conversion" },
92a864dc36Sdarran { EDT_BADCONV, "Incomplete printf conversion" },
93a864dc36Sdarran { EDT_BADERROR, "Invalid library ERROR action" },
94a864dc36Sdarran { EDT_ERRABORT, "Abort due to error" },
95a864dc36Sdarran { EDT_DROPABORT, "Abort due to drop" },
96a864dc36Sdarran { EDT_DIRABORT, "Abort explicitly directed" },
97a864dc36Sdarran { EDT_BADRVAL, "Invalid return value from callback" },
98a864dc36Sdarran { EDT_BADNORMAL, "Invalid normalization" },
99a864dc36Sdarran { EDT_BUFTOOSMALL, "Enabling exceeds size of buffer" },
100a864dc36Sdarran { EDT_BADTRUNC, "Invalid truncation" },
101a864dc36Sdarran { EDT_BUSY, "DTrace cannot be used when kernel debugger is active" },
102a864dc36Sdarran { EDT_ACCESS, "DTrace requires additional privileges" },
103a864dc36Sdarran { EDT_NOENT, "DTrace device not available on system" },
104a864dc36Sdarran { EDT_BRICKED, "Abort due to systemic unresponsiveness" },
105a864dc36Sdarran { EDT_HARDWIRE, "Failed to load language definitions" },
106a864dc36Sdarran { EDT_ELFVERSION, "libelf is out-of-date with respect to libdtrace" },
107a864dc36Sdarran { EDT_NOBUFFERED, "Attempt to buffer output without handler" },
108a864dc36Sdarran { EDT_UNSTABLE, "Description matched an unstable set of probes" },
109a864dc36Sdarran { EDT_BADSETOPT, "Invalid setopt() library action" },
110a864dc36Sdarran { EDT_BADSTACKPC, "Invalid stack program counter size" },
111a864dc36Sdarran { EDT_BADAGGVAR, "Invalid aggregation variable identifier" },
112a252d550Shaad { EDT_OVERSION, "Client requested deprecated version of library" },
113*920211a7Schristos { EDT_ENABLING_ERR, "Failed to enable probe" },
114*920211a7Schristos { EDT_NOPROBES, "No probe sites found for declared provider" },
115*920211a7Schristos { EDT_CANTLOAD, "Failed to load module" },
116a864dc36Sdarran };
117a864dc36Sdarran
118a864dc36Sdarran static const int _dt_nerr = sizeof (_dt_errlist) / sizeof (_dt_errlist[0]);
119a864dc36Sdarran
120a864dc36Sdarran const char *
dtrace_errmsg(dtrace_hdl_t * dtp,int error)121a864dc36Sdarran dtrace_errmsg(dtrace_hdl_t *dtp, int error)
122a864dc36Sdarran {
123a864dc36Sdarran const char *str;
124a864dc36Sdarran int i;
125a864dc36Sdarran
126a864dc36Sdarran if (error == EDT_COMPILER && dtp != NULL && dtp->dt_errmsg[0] != '\0')
127a864dc36Sdarran str = dtp->dt_errmsg;
128a864dc36Sdarran else if (error == EDT_CTF && dtp != NULL && dtp->dt_ctferr != 0)
129a864dc36Sdarran str = ctf_errmsg(dtp->dt_ctferr);
130a864dc36Sdarran else if (error >= EDT_BASE && (error - EDT_BASE) < _dt_nerr) {
131a864dc36Sdarran for (i = 0; i < _dt_nerr; i++) {
132a864dc36Sdarran if (_dt_errlist[i].err == error)
133a864dc36Sdarran return (_dt_errlist[i].msg);
134a864dc36Sdarran }
135a864dc36Sdarran str = NULL;
136a864dc36Sdarran } else
137a864dc36Sdarran str = strerror(error);
138a864dc36Sdarran
139a864dc36Sdarran return (str ? str : "Unknown error");
140a864dc36Sdarran }
141a864dc36Sdarran
142a864dc36Sdarran int
dtrace_errno(dtrace_hdl_t * dtp)143a864dc36Sdarran dtrace_errno(dtrace_hdl_t *dtp)
144a864dc36Sdarran {
145a864dc36Sdarran return (dtp->dt_errno);
146a864dc36Sdarran }
147a864dc36Sdarran
148*920211a7Schristos #ifdef illumos
149a864dc36Sdarran int
dt_set_errno(dtrace_hdl_t * dtp,int err)150a864dc36Sdarran dt_set_errno(dtrace_hdl_t *dtp, int err)
151a864dc36Sdarran {
152a864dc36Sdarran dtp->dt_errno = err;
153a864dc36Sdarran return (-1);
154a864dc36Sdarran }
155bb8023b5Sdarran #else
156bb8023b5Sdarran int
_dt_set_errno(dtrace_hdl_t * dtp,int err,const char * errfile,int errline)157bb8023b5Sdarran _dt_set_errno(dtrace_hdl_t *dtp, int err, const char *errfile, int errline)
158bb8023b5Sdarran {
159bb8023b5Sdarran dtp->dt_errno = err;
160bb8023b5Sdarran dtp->dt_errfile = errfile;
161bb8023b5Sdarran dtp->dt_errline = errline;
162bb8023b5Sdarran return (-1);
163bb8023b5Sdarran }
164bb8023b5Sdarran
dt_get_errloc(dtrace_hdl_t * dtp,const char ** p_errfile,int * p_errline)165bb8023b5Sdarran void dt_get_errloc(dtrace_hdl_t *dtp, const char **p_errfile, int *p_errline)
166bb8023b5Sdarran {
167bb8023b5Sdarran *p_errfile = dtp->dt_errfile;
168bb8023b5Sdarran *p_errline = dtp->dt_errline;
169bb8023b5Sdarran }
170bb8023b5Sdarran #endif
171a864dc36Sdarran
172a864dc36Sdarran void
dt_set_errmsg(dtrace_hdl_t * dtp,const char * errtag,const char * region,const char * filename,int lineno,const char * format,va_list ap)173a864dc36Sdarran dt_set_errmsg(dtrace_hdl_t *dtp, const char *errtag, const char *region,
174a864dc36Sdarran const char *filename, int lineno, const char *format, va_list ap)
175a864dc36Sdarran {
176a864dc36Sdarran size_t len, n;
177a864dc36Sdarran char *p, *s;
178a864dc36Sdarran
179a864dc36Sdarran s = dtp->dt_errmsg;
180a864dc36Sdarran n = sizeof (dtp->dt_errmsg);
181a864dc36Sdarran
182a864dc36Sdarran if (errtag != NULL && (yypcb->pcb_cflags & DTRACE_C_ETAGS))
183a864dc36Sdarran (void) snprintf(s, n, "[%s] ", errtag);
184a864dc36Sdarran else
185a864dc36Sdarran s[0] = '\0';
186a864dc36Sdarran
187a864dc36Sdarran len = strlen(dtp->dt_errmsg);
188a864dc36Sdarran s = dtp->dt_errmsg + len;
189a864dc36Sdarran n = sizeof (dtp->dt_errmsg) - len;
190a864dc36Sdarran
191a864dc36Sdarran if (filename == NULL)
192a864dc36Sdarran filename = dtp->dt_filetag;
193a864dc36Sdarran
194a864dc36Sdarran if (filename != NULL)
195a864dc36Sdarran (void) snprintf(s, n, "\"%s\", line %d: ", filename, lineno);
196a864dc36Sdarran else if (lineno != 0)
197a864dc36Sdarran (void) snprintf(s, n, "line %d: ", lineno);
198a864dc36Sdarran else if (region != NULL)
199a864dc36Sdarran (void) snprintf(s, n, "in %s: ", region);
200a864dc36Sdarran
201a864dc36Sdarran len = strlen(dtp->dt_errmsg);
202a864dc36Sdarran s = dtp->dt_errmsg + len;
203a864dc36Sdarran n = sizeof (dtp->dt_errmsg) - len;
204a864dc36Sdarran (void) vsnprintf(s, n, format, ap);
205a864dc36Sdarran
206a864dc36Sdarran if ((p = strrchr(dtp->dt_errmsg, '\n')) != NULL)
207a864dc36Sdarran *p = '\0'; /* remove trailing \n from message buffer */
208a864dc36Sdarran
209a864dc36Sdarran dtp->dt_errtag = errtag;
210a864dc36Sdarran }
211a864dc36Sdarran
212a864dc36Sdarran /*ARGSUSED*/
213a864dc36Sdarran const char *
dtrace_faultstr(dtrace_hdl_t * dtp,int fault)214a864dc36Sdarran dtrace_faultstr(dtrace_hdl_t *dtp, int fault)
215a864dc36Sdarran {
216a864dc36Sdarran int i;
217a864dc36Sdarran
218a864dc36Sdarran static const struct {
219a864dc36Sdarran int code;
220a864dc36Sdarran const char *str;
221a864dc36Sdarran } faults[] = {
222a864dc36Sdarran { DTRACEFLT_BADADDR, "invalid address" },
223a864dc36Sdarran { DTRACEFLT_BADALIGN, "invalid alignment" },
224a864dc36Sdarran { DTRACEFLT_ILLOP, "illegal operation" },
225a864dc36Sdarran { DTRACEFLT_DIVZERO, "divide-by-zero" },
226a864dc36Sdarran { DTRACEFLT_NOSCRATCH, "out of scratch space" },
227a864dc36Sdarran { DTRACEFLT_KPRIV, "invalid kernel access" },
228a864dc36Sdarran { DTRACEFLT_UPRIV, "invalid user access" },
229a864dc36Sdarran { DTRACEFLT_TUPOFLOW, "tuple stack overflow" },
230a864dc36Sdarran { DTRACEFLT_BADSTACK, "bad stack" },
231a864dc36Sdarran { DTRACEFLT_LIBRARY, "library-level fault" },
232a864dc36Sdarran { 0, NULL }
233a864dc36Sdarran };
234a864dc36Sdarran
235a864dc36Sdarran for (i = 0; faults[i].str != NULL; i++) {
236a864dc36Sdarran if (faults[i].code == fault)
237a864dc36Sdarran return (faults[i].str);
238a864dc36Sdarran }
239a864dc36Sdarran
240a864dc36Sdarran return ("unknown fault");
241a864dc36Sdarran }
242