Print this page
5218 posix definition of NULL
correct unistd.h and iso/stddef_iso.h
update gate source affected
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libdtrace/common/dt_handle.c
+++ new/usr/src/lib/libdtrace/common/dt_handle.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #pragma ident "%Z%%M% %I% %E% SMI"
27 27
28 28 #include <stddef.h>
29 29 #include <stdlib.h>
30 30 #include <strings.h>
31 31 #include <errno.h>
32 32 #include <unistd.h>
33 33 #include <assert.h>
34 34 #include <alloca.h>
35 35
36 36 #include <dt_impl.h>
37 37 #include <dt_program.h>
38 38
39 39 static const char _dt_errprog[] =
40 40 "dtrace:::ERROR"
41 41 "{"
42 42 " trace(arg1);"
43 43 " trace(arg2);"
44 44 " trace(arg3);"
45 45 " trace(arg4);"
46 46 " trace(arg5);"
47 47 "}";
48 48
49 49 int
50 50 dtrace_handle_err(dtrace_hdl_t *dtp, dtrace_handle_err_f *hdlr, void *arg)
51 51 {
52 52 dtrace_prog_t *pgp = NULL;
53 53 dt_stmt_t *stp;
54 54 dtrace_ecbdesc_t *edp;
55 55
56 56 /*
57 57 * We don't currently support multiple error handlers.
58 58 */
59 59 if (dtp->dt_errhdlr != NULL)
60 60 return (dt_set_errno(dtp, EALREADY));
61 61
62 62 /*
63 63 * If the DTRACEOPT_GRABANON is enabled, the anonymous enabling will
64 64 * already have a dtrace:::ERROR probe enabled; save 'hdlr' and 'arg'
65 65 * but do not bother compiling and enabling _dt_errprog.
66 66 */
67 67 if (dtp->dt_options[DTRACEOPT_GRABANON] != DTRACEOPT_UNSET)
68 68 goto out;
69 69
70 70 if ((pgp = dtrace_program_strcompile(dtp, _dt_errprog,
71 71 DTRACE_PROBESPEC_NAME, DTRACE_C_ZDEFS, 0, NULL)) == NULL)
72 72 return (dt_set_errno(dtp, dtrace_errno(dtp)));
73 73
74 74 stp = dt_list_next(&pgp->dp_stmts);
75 75 assert(stp != NULL);
76 76
77 77 edp = stp->ds_desc->dtsd_ecbdesc;
78 78 assert(edp != NULL);
79 79 edp->dted_uarg = DT_ECB_ERROR;
80 80
81 81 out:
82 82 dtp->dt_errhdlr = hdlr;
83 83 dtp->dt_errarg = arg;
84 84 dtp->dt_errprog = pgp;
85 85
86 86 return (0);
87 87 }
88 88
89 89 int
90 90 dtrace_handle_drop(dtrace_hdl_t *dtp, dtrace_handle_drop_f *hdlr, void *arg)
91 91 {
92 92 if (dtp->dt_drophdlr != NULL)
93 93 return (dt_set_errno(dtp, EALREADY));
94 94
95 95 dtp->dt_drophdlr = hdlr;
96 96 dtp->dt_droparg = arg;
97 97
98 98 return (0);
99 99 }
100 100
101 101 int
102 102 dtrace_handle_proc(dtrace_hdl_t *dtp, dtrace_handle_proc_f *hdlr, void *arg)
103 103 {
104 104 if (dtp->dt_prochdlr != NULL)
105 105 return (dt_set_errno(dtp, EALREADY));
106 106
107 107 dtp->dt_prochdlr = hdlr;
108 108 dtp->dt_procarg = arg;
109 109
110 110 return (0);
111 111 }
112 112
113 113 int
114 114 dtrace_handle_buffered(dtrace_hdl_t *dtp, dtrace_handle_buffered_f *hdlr,
115 115 void *arg)
116 116 {
117 117 if (dtp->dt_bufhdlr != NULL)
118 118 return (dt_set_errno(dtp, EALREADY));
119 119
120 120 if (hdlr == NULL)
121 121 return (dt_set_errno(dtp, EINVAL));
122 122
123 123 dtp->dt_bufhdlr = hdlr;
124 124 dtp->dt_bufarg = arg;
125 125
126 126 return (0);
127 127 }
128 128
129 129 int
130 130 dtrace_handle_setopt(dtrace_hdl_t *dtp, dtrace_handle_setopt_f *hdlr,
131 131 void *arg)
132 132 {
133 133 if (hdlr == NULL)
134 134 return (dt_set_errno(dtp, EINVAL));
135 135
136 136 dtp->dt_setopthdlr = hdlr;
137 137 dtp->dt_setoptarg = arg;
138 138
139 139 return (0);
140 140 }
141 141
142 142 #define DT_REC(type, ndx) *((type *)((uintptr_t)data->dtpda_data + \
143 143 epd->dtepd_rec[(ndx)].dtrd_offset))
144 144
145 145 static int
146 146 dt_handle_err(dtrace_hdl_t *dtp, dtrace_probedata_t *data)
147 147 {
148 148 dtrace_eprobedesc_t *epd = data->dtpda_edesc, *errepd;
149 149 dtrace_probedesc_t *pd = data->dtpda_pdesc, *errpd;
150 150 dtrace_errdata_t err;
151 151 dtrace_epid_t epid;
152 152
153 153 char where[30];
154 154 char details[30];
155 155 char offinfo[30];
156 156 const int slop = 80;
157 157 const char *faultstr;
158 158 char *str;
159 159 int len;
160 160
161 161 assert(epd->dtepd_uarg == DT_ECB_ERROR);
162 162
163 163 if (epd->dtepd_nrecs != 5 || strcmp(pd->dtpd_provider, "dtrace") != 0 ||
164 164 strcmp(pd->dtpd_name, "ERROR") != 0)
165 165 return (dt_set_errno(dtp, EDT_BADERROR));
166 166
167 167 /*
168 168 * This is an error. We have the following items here: EPID,
169 169 * faulting action, DIF offset, fault code and faulting address.
170 170 */
171 171 epid = (uint32_t)DT_REC(uint64_t, 0);
172 172
173 173 if (dt_epid_lookup(dtp, epid, &errepd, &errpd) != 0)
174 174 return (dt_set_errno(dtp, EDT_BADERROR));
175 175
176 176 err.dteda_edesc = errepd;
177 177 err.dteda_pdesc = errpd;
178 178 err.dteda_cpu = data->dtpda_cpu;
179 179 err.dteda_action = (int)DT_REC(uint64_t, 1);
180 180 err.dteda_offset = (int)DT_REC(uint64_t, 2);
181 181 err.dteda_fault = (int)DT_REC(uint64_t, 3);
182 182 err.dteda_addr = DT_REC(uint64_t, 4);
183 183
184 184 faultstr = dtrace_faultstr(dtp, err.dteda_fault);
185 185 len = sizeof (where) + sizeof (offinfo) + strlen(faultstr) +
186 186 strlen(errpd->dtpd_provider) + strlen(errpd->dtpd_mod) +
187 187 strlen(errpd->dtpd_name) + strlen(errpd->dtpd_func) +
188 188 slop;
189 189
190 190 str = (char *)alloca(len);
191 191
192 192 if (err.dteda_action == 0) {
193 193 (void) sprintf(where, "predicate");
194 194 } else {
195 195 (void) sprintf(where, "action #%d", err.dteda_action);
196 196 }
197 197
198 198 if (err.dteda_offset != -1) {
199 199 (void) sprintf(offinfo, " at DIF offset %d", err.dteda_offset);
200 200 } else {
201 201 offinfo[0] = 0;
202 202 }
203 203
204 204 switch (err.dteda_fault) {
205 205 case DTRACEFLT_BADADDR:
206 206 case DTRACEFLT_BADALIGN:
207 207 case DTRACEFLT_BADSTACK:
208 208 (void) sprintf(details, " (0x%llx)",
209 209 (u_longlong_t)err.dteda_addr);
210 210 break;
211 211
212 212 default:
213 213 details[0] = 0;
214 214 }
215 215
216 216 (void) snprintf(str, len, "error on enabled probe ID %u "
217 217 "(ID %u: %s:%s:%s:%s): %s%s in %s%s\n",
218 218 epid, errpd->dtpd_id, errpd->dtpd_provider,
219 219 errpd->dtpd_mod, errpd->dtpd_func,
220 220 errpd->dtpd_name, dtrace_faultstr(dtp, err.dteda_fault),
221 221 details, where, offinfo);
222 222
223 223 err.dteda_msg = str;
224 224
225 225 if (dtp->dt_errhdlr == NULL)
226 226 return (dt_set_errno(dtp, EDT_ERRABORT));
227 227
228 228 if ((*dtp->dt_errhdlr)(&err, dtp->dt_errarg) == DTRACE_HANDLE_ABORT)
229 229 return (dt_set_errno(dtp, EDT_ERRABORT));
230 230
231 231 return (0);
232 232 }
233 233
234 234 int
235 235 dt_handle_liberr(dtrace_hdl_t *dtp, const dtrace_probedata_t *data,
236 236 const char *faultstr)
237 237 {
238 238 dtrace_probedesc_t *errpd = data->dtpda_pdesc;
239 239 dtrace_errdata_t err;
↓ open down ↓ |
239 lines elided |
↑ open up ↑ |
240 240 const int slop = 80;
241 241 char *str;
242 242 int len;
243 243
244 244 err.dteda_edesc = data->dtpda_edesc;
245 245 err.dteda_pdesc = errpd;
246 246 err.dteda_cpu = data->dtpda_cpu;
247 247 err.dteda_action = -1;
248 248 err.dteda_offset = -1;
249 249 err.dteda_fault = DTRACEFLT_LIBRARY;
250 - err.dteda_addr = NULL;
250 + err.dteda_addr = 0L;
251 251
252 252 len = strlen(faultstr) +
253 253 strlen(errpd->dtpd_provider) + strlen(errpd->dtpd_mod) +
254 254 strlen(errpd->dtpd_name) + strlen(errpd->dtpd_func) +
255 255 slop;
256 256
257 257 str = alloca(len);
258 258
259 259 (void) snprintf(str, len, "error on enabled probe ID %u "
260 260 "(ID %u: %s:%s:%s:%s): %s\n",
261 261 data->dtpda_edesc->dtepd_epid,
262 262 errpd->dtpd_id, errpd->dtpd_provider,
263 263 errpd->dtpd_mod, errpd->dtpd_func,
264 264 errpd->dtpd_name, faultstr);
265 265
266 266 err.dteda_msg = str;
267 267
268 268 if (dtp->dt_errhdlr == NULL)
269 269 return (dt_set_errno(dtp, EDT_ERRABORT));
270 270
271 271 if ((*dtp->dt_errhdlr)(&err, dtp->dt_errarg) == DTRACE_HANDLE_ABORT)
272 272 return (dt_set_errno(dtp, EDT_ERRABORT));
273 273
274 274 return (0);
275 275 }
276 276
277 277 #define DROPTAG(x) x, #x
278 278
279 279 static const struct {
280 280 dtrace_dropkind_t dtdrg_kind;
281 281 char *dtdrg_tag;
282 282 } _dt_droptags[] = {
283 283 { DROPTAG(DTRACEDROP_PRINCIPAL) },
284 284 { DROPTAG(DTRACEDROP_AGGREGATION) },
285 285 { DROPTAG(DTRACEDROP_DYNAMIC) },
286 286 { DROPTAG(DTRACEDROP_DYNRINSE) },
287 287 { DROPTAG(DTRACEDROP_DYNDIRTY) },
288 288 { DROPTAG(DTRACEDROP_SPEC) },
289 289 { DROPTAG(DTRACEDROP_SPECBUSY) },
290 290 { DROPTAG(DTRACEDROP_SPECUNAVAIL) },
291 291 { DROPTAG(DTRACEDROP_DBLERROR) },
292 292 { DROPTAG(DTRACEDROP_STKSTROVERFLOW) },
293 293 { 0, NULL }
294 294 };
295 295
296 296 static const char *
297 297 dt_droptag(dtrace_dropkind_t kind)
298 298 {
299 299 int i;
300 300
301 301 for (i = 0; _dt_droptags[i].dtdrg_tag != NULL; i++) {
302 302 if (_dt_droptags[i].dtdrg_kind == kind)
303 303 return (_dt_droptags[i].dtdrg_tag);
304 304 }
305 305
306 306 return ("DTRACEDROP_UNKNOWN");
307 307 }
308 308
309 309 int
310 310 dt_handle_cpudrop(dtrace_hdl_t *dtp, processorid_t cpu,
311 311 dtrace_dropkind_t what, uint64_t howmany)
312 312 {
313 313 dtrace_dropdata_t drop;
314 314 char str[80], *s;
315 315 int size;
316 316
317 317 assert(what == DTRACEDROP_PRINCIPAL || what == DTRACEDROP_AGGREGATION);
318 318
319 319 bzero(&drop, sizeof (drop));
320 320 drop.dtdda_handle = dtp;
321 321 drop.dtdda_cpu = cpu;
322 322 drop.dtdda_kind = what;
323 323 drop.dtdda_drops = howmany;
324 324 drop.dtdda_msg = str;
325 325
326 326 if (dtp->dt_droptags) {
327 327 (void) snprintf(str, sizeof (str), "[%s] ", dt_droptag(what));
328 328 s = &str[strlen(str)];
329 329 size = sizeof (str) - (s - str);
330 330 } else {
331 331 s = str;
332 332 size = sizeof (str);
333 333 }
334 334
335 335 (void) snprintf(s, size, "%llu %sdrop%s on CPU %d\n",
336 336 howmany, what == DTRACEDROP_PRINCIPAL ? "" : "aggregation ",
337 337 howmany > 1 ? "s" : "", cpu);
338 338
339 339 if (dtp->dt_drophdlr == NULL)
340 340 return (dt_set_errno(dtp, EDT_DROPABORT));
341 341
342 342 if ((*dtp->dt_drophdlr)(&drop, dtp->dt_droparg) == DTRACE_HANDLE_ABORT)
343 343 return (dt_set_errno(dtp, EDT_DROPABORT));
344 344
345 345 return (0);
346 346 }
347 347
348 348 static const struct {
349 349 dtrace_dropkind_t dtdrt_kind;
350 350 uintptr_t dtdrt_offset;
351 351 const char *dtdrt_str;
352 352 const char *dtdrt_msg;
353 353 } _dt_droptab[] = {
354 354 { DTRACEDROP_DYNAMIC,
355 355 offsetof(dtrace_status_t, dtst_dyndrops),
356 356 "dynamic variable drop" },
357 357
358 358 { DTRACEDROP_DYNRINSE,
359 359 offsetof(dtrace_status_t, dtst_dyndrops_rinsing),
360 360 "dynamic variable drop", " with non-empty rinsing list" },
361 361
362 362 { DTRACEDROP_DYNDIRTY,
363 363 offsetof(dtrace_status_t, dtst_dyndrops_dirty),
364 364 "dynamic variable drop", " with non-empty dirty list" },
365 365
366 366 { DTRACEDROP_SPEC,
367 367 offsetof(dtrace_status_t, dtst_specdrops),
368 368 "speculative drop" },
369 369
370 370 { DTRACEDROP_SPECBUSY,
371 371 offsetof(dtrace_status_t, dtst_specdrops_busy),
372 372 "failed speculation", " (available buffer(s) still busy)" },
373 373
374 374 { DTRACEDROP_SPECUNAVAIL,
375 375 offsetof(dtrace_status_t, dtst_specdrops_unavail),
376 376 "failed speculation", " (no speculative buffer available)" },
377 377
378 378 { DTRACEDROP_STKSTROVERFLOW,
379 379 offsetof(dtrace_status_t, dtst_stkstroverflows),
380 380 "jstack()/ustack() string table overflow" },
381 381
382 382 { DTRACEDROP_DBLERROR,
383 383 offsetof(dtrace_status_t, dtst_dblerrors),
384 384 "error", " in ERROR probe enabling" },
385 385
386 386 { 0, 0, NULL }
387 387 };
388 388
389 389 int
390 390 dt_handle_status(dtrace_hdl_t *dtp, dtrace_status_t *old, dtrace_status_t *new)
391 391 {
392 392 dtrace_dropdata_t drop;
393 393 char str[80], *s;
394 394 uintptr_t base = (uintptr_t)new, obase = (uintptr_t)old;
395 395 int i, size;
396 396
397 397 bzero(&drop, sizeof (drop));
398 398 drop.dtdda_handle = dtp;
399 399 drop.dtdda_cpu = DTRACE_CPUALL;
400 400 drop.dtdda_msg = str;
401 401
402 402 /*
403 403 * First, check to see if we've been killed -- in which case we abort.
404 404 */
405 405 if (new->dtst_killed && !old->dtst_killed)
406 406 return (dt_set_errno(dtp, EDT_BRICKED));
407 407
408 408 for (i = 0; _dt_droptab[i].dtdrt_str != NULL; i++) {
409 409 uintptr_t naddr = base + _dt_droptab[i].dtdrt_offset;
410 410 uintptr_t oaddr = obase + _dt_droptab[i].dtdrt_offset;
411 411
412 412 uint64_t nval = *((uint64_t *)naddr);
413 413 uint64_t oval = *((uint64_t *)oaddr);
414 414
415 415 if (nval == oval)
416 416 continue;
417 417
418 418 if (dtp->dt_droptags) {
419 419 (void) snprintf(str, sizeof (str), "[%s] ",
420 420 dt_droptag(_dt_droptab[i].dtdrt_kind));
421 421 s = &str[strlen(str)];
422 422 size = sizeof (str) - (s - str);
423 423 } else {
424 424 s = str;
425 425 size = sizeof (str);
426 426 }
427 427
428 428 (void) snprintf(s, size, "%llu %s%s%s\n", nval - oval,
429 429 _dt_droptab[i].dtdrt_str, (nval - oval > 1) ? "s" : "",
430 430 _dt_droptab[i].dtdrt_msg != NULL ?
431 431 _dt_droptab[i].dtdrt_msg : "");
432 432
433 433 drop.dtdda_kind = _dt_droptab[i].dtdrt_kind;
434 434 drop.dtdda_total = nval;
435 435 drop.dtdda_drops = nval - oval;
436 436
437 437 if (dtp->dt_drophdlr == NULL)
438 438 return (dt_set_errno(dtp, EDT_DROPABORT));
439 439
440 440 if ((*dtp->dt_drophdlr)(&drop,
441 441 dtp->dt_droparg) == DTRACE_HANDLE_ABORT)
442 442 return (dt_set_errno(dtp, EDT_DROPABORT));
443 443 }
444 444
445 445 return (0);
446 446 }
447 447
448 448 int
449 449 dt_handle_setopt(dtrace_hdl_t *dtp, dtrace_setoptdata_t *data)
450 450 {
451 451 void *arg = dtp->dt_setoptarg;
452 452
453 453 if (dtp->dt_setopthdlr == NULL)
454 454 return (0);
455 455
456 456 if ((*dtp->dt_setopthdlr)(data, arg) == DTRACE_HANDLE_ABORT)
457 457 return (dt_set_errno(dtp, EDT_DIRABORT));
458 458
459 459 return (0);
460 460 }
461 461
462 462 int
463 463 dt_handle(dtrace_hdl_t *dtp, dtrace_probedata_t *data)
464 464 {
465 465 dtrace_eprobedesc_t *epd = data->dtpda_edesc;
466 466 int rval;
467 467
468 468 switch (epd->dtepd_uarg) {
469 469 case DT_ECB_ERROR:
470 470 rval = dt_handle_err(dtp, data);
471 471 break;
472 472
473 473 default:
474 474 return (DTRACE_CONSUME_THIS);
475 475 }
476 476
477 477 if (rval == 0)
478 478 return (DTRACE_CONSUME_NEXT);
479 479
480 480 return (DTRACE_CONSUME_ERROR);
481 481 }
↓ open down ↓ |
221 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX