Print this page
4471 DTrace count() with histogram
4472 DTrace full width distribution histograms
4473 DTrace frequency trails
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libdtrace/common/dt_options.c
+++ new/usr/src/lib/libdtrace/common/dt_options.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]
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 /*
28 + * Copyright (c) 2013, Joyent, Inc. All rights reserved.
28 29 * Copyright (c) 2012 by Delphix. All rights reserved.
29 30 */
30 31
31 32 #include <sys/resource.h>
32 33 #include <sys/mman.h>
33 34 #include <sys/types.h>
34 35
35 36 #include <strings.h>
36 37 #include <signal.h>
37 38 #include <stdlib.h>
38 39 #include <unistd.h>
39 40 #include <limits.h>
40 41 #include <alloca.h>
41 42 #include <errno.h>
42 43 #include <fcntl.h>
43 44
44 45 #include <dt_impl.h>
45 46 #include <dt_string.h>
46 47
47 48 static int
48 49 dt_opt_agg(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
49 50 {
50 51 dt_aggregate_t *agp = &dtp->dt_aggregate;
51 52
52 53 if (arg != NULL)
53 54 return (dt_set_errno(dtp, EDT_BADOPTVAL));
54 55
55 56 agp->dtat_flags |= option;
56 57 return (0);
57 58 }
58 59
59 60 /*ARGSUSED*/
60 61 static int
61 62 dt_opt_amin(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
62 63 {
63 64 char str[DTRACE_ATTR2STR_MAX];
64 65 dtrace_attribute_t attr;
65 66
66 67 if (arg == NULL || dtrace_str2attr(arg, &attr) == -1)
67 68 return (dt_set_errno(dtp, EDT_BADOPTVAL));
68 69
69 70 dt_dprintf("set compiler attribute minimum to %s\n",
70 71 dtrace_attr2str(attr, str, sizeof (str)));
71 72
72 73 if (dtp->dt_pcb != NULL) {
73 74 dtp->dt_pcb->pcb_cflags |= DTRACE_C_EATTR;
74 75 dtp->dt_pcb->pcb_amin = attr;
75 76 } else {
76 77 dtp->dt_cflags |= DTRACE_C_EATTR;
77 78 dtp->dt_amin = attr;
78 79 }
79 80
80 81 return (0);
81 82 }
82 83
83 84 static void
84 85 dt_coredump(void)
85 86 {
86 87 const char msg[] = "libdtrace DEBUG: [ forcing coredump ]\n";
87 88
88 89 struct sigaction act;
89 90 struct rlimit lim;
90 91
91 92 (void) write(STDERR_FILENO, msg, sizeof (msg) - 1);
92 93
93 94 act.sa_handler = SIG_DFL;
94 95 act.sa_flags = 0;
95 96
96 97 (void) sigemptyset(&act.sa_mask);
97 98 (void) sigaction(SIGABRT, &act, NULL);
98 99
99 100 lim.rlim_cur = RLIM_INFINITY;
100 101 lim.rlim_max = RLIM_INFINITY;
101 102
102 103 (void) setrlimit(RLIMIT_CORE, &lim);
103 104 abort();
104 105 }
105 106
106 107 /*ARGSUSED*/
107 108 static int
108 109 dt_opt_core(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
109 110 {
110 111 static int enabled = 0;
111 112
112 113 if (arg != NULL)
113 114 return (dt_set_errno(dtp, EDT_BADOPTVAL));
114 115
115 116 if (enabled++ || atexit(dt_coredump) == 0)
116 117 return (0);
117 118
118 119 return (dt_set_errno(dtp, errno));
119 120 }
120 121
121 122 /*ARGSUSED*/
122 123 static int
123 124 dt_opt_cpp_hdrs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
124 125 {
125 126 if (arg != NULL)
126 127 return (dt_set_errno(dtp, EDT_BADOPTVAL));
127 128
128 129 if (dtp->dt_pcb != NULL)
129 130 return (dt_set_errno(dtp, EDT_BADOPTCTX));
130 131
131 132 if (dt_cpp_add_arg(dtp, "-H") == NULL)
132 133 return (dt_set_errno(dtp, EDT_NOMEM));
133 134
134 135 return (0);
135 136 }
136 137
137 138 /*ARGSUSED*/
138 139 static int
139 140 dt_opt_cpp_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
140 141 {
141 142 char *cpp;
142 143
143 144 if (arg == NULL)
144 145 return (dt_set_errno(dtp, EDT_BADOPTVAL));
145 146
146 147 if (dtp->dt_pcb != NULL)
147 148 return (dt_set_errno(dtp, EDT_BADOPTCTX));
148 149
149 150 if ((cpp = strdup(arg)) == NULL)
150 151 return (dt_set_errno(dtp, EDT_NOMEM));
151 152
152 153 dtp->dt_cpp_argv[0] = (char *)strbasename(cpp);
153 154 free(dtp->dt_cpp_path);
154 155 dtp->dt_cpp_path = cpp;
155 156
156 157 return (0);
157 158 }
158 159
159 160 static int
160 161 dt_opt_cpp_opts(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
161 162 {
162 163 char *buf;
163 164 size_t len;
164 165 const char *opt = (const char *)option;
165 166
166 167 if (opt == NULL || arg == NULL)
167 168 return (dt_set_errno(dtp, EDT_BADOPTVAL));
168 169
169 170 if (dtp->dt_pcb != NULL)
170 171 return (dt_set_errno(dtp, EDT_BADOPTCTX));
171 172
172 173 len = strlen(opt) + strlen(arg) + 1;
173 174 buf = alloca(len);
174 175
175 176 (void) strcpy(buf, opt);
176 177 (void) strcat(buf, arg);
177 178
178 179 if (dt_cpp_add_arg(dtp, buf) == NULL)
179 180 return (dt_set_errno(dtp, EDT_NOMEM));
180 181
181 182 return (0);
182 183 }
183 184
184 185 /*ARGSUSED*/
185 186 static int
186 187 dt_opt_ctypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
187 188 {
188 189 int fd;
189 190
190 191 if (arg == NULL)
191 192 return (dt_set_errno(dtp, EDT_BADOPTVAL));
192 193
193 194 if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1)
194 195 return (dt_set_errno(dtp, errno));
195 196
196 197 (void) close(dtp->dt_cdefs_fd);
197 198 dtp->dt_cdefs_fd = fd;
198 199 return (0);
199 200 }
200 201
201 202 /*ARGSUSED*/
202 203 static int
203 204 dt_opt_droptags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
204 205 {
205 206 dtp->dt_droptags = 1;
206 207 return (0);
207 208 }
208 209
209 210 /*ARGSUSED*/
210 211 static int
211 212 dt_opt_dtypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
212 213 {
213 214 int fd;
214 215
215 216 if (arg == NULL)
216 217 return (dt_set_errno(dtp, EDT_BADOPTVAL));
217 218
218 219 if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1)
219 220 return (dt_set_errno(dtp, errno));
220 221
221 222 (void) close(dtp->dt_ddefs_fd);
222 223 dtp->dt_ddefs_fd = fd;
223 224 return (0);
224 225 }
225 226
226 227 /*ARGSUSED*/
227 228 static int
228 229 dt_opt_debug(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
229 230 {
230 231 if (arg != NULL)
231 232 return (dt_set_errno(dtp, EDT_BADOPTVAL));
232 233
233 234 _dtrace_debug = 1;
234 235 return (0);
235 236 }
236 237
237 238 /*ARGSUSED*/
238 239 static int
239 240 dt_opt_iregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
240 241 {
241 242 int n;
242 243
243 244 if (arg == NULL || (n = atoi(arg)) <= 0)
244 245 return (dt_set_errno(dtp, EDT_BADOPTVAL));
245 246
246 247 dtp->dt_conf.dtc_difintregs = n;
247 248 return (0);
248 249 }
249 250
250 251 /*ARGSUSED*/
251 252 static int
252 253 dt_opt_lazyload(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
253 254 {
254 255 dtp->dt_lazyload = 1;
255 256
256 257 return (0);
257 258 }
258 259
259 260 /*ARGSUSED*/
260 261 static int
261 262 dt_opt_ld_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
262 263 {
263 264 char *ld;
264 265
265 266 if (arg == NULL)
266 267 return (dt_set_errno(dtp, EDT_BADOPTVAL));
267 268
268 269 if (dtp->dt_pcb != NULL)
269 270 return (dt_set_errno(dtp, EDT_BADOPTCTX));
270 271
271 272 if ((ld = strdup(arg)) == NULL)
272 273 return (dt_set_errno(dtp, EDT_NOMEM));
273 274
274 275 free(dtp->dt_ld_path);
275 276 dtp->dt_ld_path = ld;
276 277
277 278 return (0);
278 279 }
279 280
280 281 /*ARGSUSED*/
281 282 static int
282 283 dt_opt_libdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
283 284 {
284 285 dt_dirpath_t *dp;
285 286
286 287 if (arg == NULL)
287 288 return (dt_set_errno(dtp, EDT_BADOPTVAL));
288 289
289 290 if ((dp = malloc(sizeof (dt_dirpath_t))) == NULL ||
290 291 (dp->dir_path = strdup(arg)) == NULL) {
291 292 free(dp);
292 293 return (dt_set_errno(dtp, EDT_NOMEM));
293 294 }
294 295
295 296 dt_list_append(&dtp->dt_lib_path, dp);
296 297 return (0);
297 298 }
298 299
299 300 /*ARGSUSED*/
300 301 static int
301 302 dt_opt_linkmode(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
302 303 {
303 304 if (arg == NULL)
304 305 return (dt_set_errno(dtp, EDT_BADOPTVAL));
305 306
306 307 if (strcmp(arg, "kernel") == 0)
307 308 dtp->dt_linkmode = DT_LINK_KERNEL;
308 309 else if (strcmp(arg, "primary") == 0)
309 310 dtp->dt_linkmode = DT_LINK_PRIMARY;
310 311 else if (strcmp(arg, "dynamic") == 0)
311 312 dtp->dt_linkmode = DT_LINK_DYNAMIC;
312 313 else if (strcmp(arg, "static") == 0)
313 314 dtp->dt_linkmode = DT_LINK_STATIC;
314 315 else
315 316 return (dt_set_errno(dtp, EDT_BADOPTVAL));
316 317
317 318 return (0);
318 319 }
319 320
320 321 /*ARGSUSED*/
321 322 static int
322 323 dt_opt_linktype(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
323 324 {
324 325 if (arg == NULL)
325 326 return (dt_set_errno(dtp, EDT_BADOPTVAL));
326 327
327 328 if (strcasecmp(arg, "elf") == 0)
328 329 dtp->dt_linktype = DT_LTYP_ELF;
↓ open down ↓ |
291 lines elided |
↑ open up ↑ |
329 330 else if (strcasecmp(arg, "dof") == 0)
330 331 dtp->dt_linktype = DT_LTYP_DOF;
331 332 else
332 333 return (dt_set_errno(dtp, EDT_BADOPTVAL));
333 334
334 335 return (0);
335 336 }
336 337
337 338 /*ARGSUSED*/
338 339 static int
340 +dt_opt_encoding(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
341 +{
342 + if (arg == NULL)
343 + return (dt_set_errno(dtp, EDT_BADOPTVAL));
344 +
345 + if (strcmp(arg, "ascii") == 0)
346 + dtp->dt_encoding = DT_ENCODING_ASCII;
347 + else if (strcmp(arg, "utf8") == 0)
348 + dtp->dt_encoding = DT_ENCODING_UTF8;
349 + else
350 + return (dt_set_errno(dtp, EDT_BADOPTVAL));
351 +
352 + return (0);
353 +}
354 +
355 +/*ARGSUSED*/
356 +static int
339 357 dt_opt_evaltime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
340 358 {
341 359 if (arg == NULL)
342 360 return (dt_set_errno(dtp, EDT_BADOPTVAL));
343 361
344 362 if (strcmp(arg, "exec") == 0)
345 363 dtp->dt_prcmode = DT_PROC_STOP_CREATE;
346 364 else if (strcmp(arg, "preinit") == 0)
347 365 dtp->dt_prcmode = DT_PROC_STOP_PREINIT;
348 366 else if (strcmp(arg, "postinit") == 0)
349 367 dtp->dt_prcmode = DT_PROC_STOP_POSTINIT;
350 368 else if (strcmp(arg, "main") == 0)
351 369 dtp->dt_prcmode = DT_PROC_STOP_MAIN;
352 370 else
353 371 return (dt_set_errno(dtp, EDT_BADOPTVAL));
354 372
355 373 return (0);
356 374 }
357 375
358 376 /*ARGSUSED*/
359 377 static int
360 378 dt_opt_pgmax(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
361 379 {
362 380 int n;
363 381
364 382 if (arg == NULL || (n = atoi(arg)) < 0)
365 383 return (dt_set_errno(dtp, EDT_BADOPTVAL));
366 384
367 385 dtp->dt_procs->dph_lrulim = n;
368 386 return (0);
369 387 }
370 388
371 389 static int
372 390 dt_opt_setenv(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
373 391 {
374 392 char **p;
375 393 char *var;
376 394 int i;
377 395
378 396 /*
379 397 * We can't effectively set environment variables from #pragma lines
380 398 * since the processes have already been spawned.
381 399 */
382 400 if (dtp->dt_pcb != NULL)
383 401 return (dt_set_errno(dtp, EDT_BADOPTCTX));
384 402
385 403 if (arg == NULL)
386 404 return (dt_set_errno(dtp, EDT_BADOPTVAL));
387 405
388 406 if (!option && strchr(arg, '=') != NULL)
389 407 return (dt_set_errno(dtp, EDT_BADOPTVAL));
390 408
391 409 for (i = 1, p = dtp->dt_proc_env; *p != NULL; i++, p++)
392 410 continue;
393 411
394 412 for (p = dtp->dt_proc_env; *p != NULL; p++) {
395 413 var = strchr(*p, '=');
396 414 if (var == NULL)
397 415 var = *p + strlen(*p);
398 416 if (strncmp(*p, arg, var - *p) == 0) {
399 417 dt_free(dtp, *p);
400 418 *p = dtp->dt_proc_env[i - 1];
401 419 dtp->dt_proc_env[i - 1] = NULL;
402 420 i--;
403 421 }
404 422 }
405 423
406 424 if (option) {
407 425 if ((var = strdup(arg)) == NULL)
408 426 return (dt_set_errno(dtp, EDT_NOMEM));
409 427
410 428 if ((p = dt_alloc(dtp, sizeof (char *) * (i + 1))) == NULL) {
411 429 dt_free(dtp, var);
412 430 return (dt_set_errno(dtp, EDT_NOMEM));
413 431 }
414 432
415 433 bcopy(dtp->dt_proc_env, p, sizeof (char *) * i);
416 434 dt_free(dtp, dtp->dt_proc_env);
417 435 dtp->dt_proc_env = p;
418 436
419 437 dtp->dt_proc_env[i - 1] = var;
420 438 dtp->dt_proc_env[i] = NULL;
421 439 }
422 440
423 441 return (0);
424 442 }
425 443
426 444 /*ARGSUSED*/
427 445 static int
428 446 dt_opt_stdc(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
429 447 {
430 448 if (arg == NULL)
431 449 return (dt_set_errno(dtp, EDT_BADOPTVAL));
432 450
433 451 if (dtp->dt_pcb != NULL)
434 452 return (dt_set_errno(dtp, EDT_BADOPTCTX));
435 453
436 454 if (strcmp(arg, "a") == 0)
437 455 dtp->dt_stdcmode = DT_STDC_XA;
438 456 else if (strcmp(arg, "c") == 0)
439 457 dtp->dt_stdcmode = DT_STDC_XC;
440 458 else if (strcmp(arg, "s") == 0)
441 459 dtp->dt_stdcmode = DT_STDC_XS;
442 460 else if (strcmp(arg, "t") == 0)
443 461 dtp->dt_stdcmode = DT_STDC_XT;
444 462 else
445 463 return (dt_set_errno(dtp, EDT_BADOPTVAL));
446 464
447 465 return (0);
448 466 }
449 467
450 468 /*ARGSUSED*/
451 469 static int
452 470 dt_opt_syslibdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
453 471 {
454 472 dt_dirpath_t *dp = dt_list_next(&dtp->dt_lib_path);
455 473 char *path;
456 474
457 475 if (arg == NULL)
458 476 return (dt_set_errno(dtp, EDT_BADOPTVAL));
459 477
460 478 if ((path = strdup(arg)) == NULL)
461 479 return (dt_set_errno(dtp, EDT_NOMEM));
462 480
463 481 free(dp->dir_path);
464 482 dp->dir_path = path;
465 483
466 484 return (0);
467 485 }
468 486
469 487 /*ARGSUSED*/
470 488 static int
471 489 dt_opt_tree(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
472 490 {
473 491 int m;
474 492
475 493 if (arg == NULL || (m = atoi(arg)) <= 0)
476 494 return (dt_set_errno(dtp, EDT_BADOPTVAL));
477 495
478 496 dtp->dt_treedump = m;
479 497 return (0);
480 498 }
481 499
482 500 /*ARGSUSED*/
483 501 static int
484 502 dt_opt_tregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
485 503 {
486 504 int n;
487 505
488 506 if (arg == NULL || (n = atoi(arg)) <= 0)
489 507 return (dt_set_errno(dtp, EDT_BADOPTVAL));
490 508
491 509 dtp->dt_conf.dtc_diftupregs = n;
492 510 return (0);
493 511 }
494 512
495 513 /*ARGSUSED*/
496 514 static int
497 515 dt_opt_xlate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
498 516 {
499 517 if (arg == NULL)
500 518 return (dt_set_errno(dtp, EDT_BADOPTVAL));
501 519
502 520 if (strcmp(arg, "dynamic") == 0)
503 521 dtp->dt_xlatemode = DT_XL_DYNAMIC;
504 522 else if (strcmp(arg, "static") == 0)
505 523 dtp->dt_xlatemode = DT_XL_STATIC;
506 524 else
507 525 return (dt_set_errno(dtp, EDT_BADOPTVAL));
508 526
509 527 return (0);
510 528 }
511 529
512 530 /*ARGSUSED*/
513 531 static int
514 532 dt_opt_cflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
515 533 {
516 534 if (arg != NULL)
517 535 return (dt_set_errno(dtp, EDT_BADOPTVAL));
518 536
519 537 if (dtp->dt_pcb != NULL)
520 538 dtp->dt_pcb->pcb_cflags |= option;
521 539 else
522 540 dtp->dt_cflags |= option;
523 541
524 542 return (0);
525 543 }
526 544
527 545 static int
528 546 dt_opt_dflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
529 547 {
530 548 if (arg != NULL)
531 549 return (dt_set_errno(dtp, EDT_BADOPTVAL));
532 550
533 551 dtp->dt_dflags |= option;
534 552 return (0);
535 553 }
536 554
537 555 static int
538 556 dt_opt_invcflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
539 557 {
540 558 if (arg != NULL)
541 559 return (dt_set_errno(dtp, EDT_BADOPTVAL));
542 560
543 561 if (dtp->dt_pcb != NULL)
544 562 dtp->dt_pcb->pcb_cflags &= ~option;
545 563 else
546 564 dtp->dt_cflags &= ~option;
547 565
548 566 return (0);
549 567 }
550 568
551 569 /*ARGSUSED*/
552 570 static int
553 571 dt_opt_version(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
554 572 {
555 573 dt_version_t v;
556 574
557 575 if (arg == NULL)
558 576 return (dt_set_errno(dtp, EDT_BADOPTVAL));
559 577
560 578 if (dt_version_str2num(arg, &v) == -1)
561 579 return (dt_set_errno(dtp, EDT_VERSINVAL));
562 580
563 581 if (!dt_version_defined(v))
564 582 return (dt_set_errno(dtp, EDT_VERSUNDEF));
565 583
566 584 return (dt_reduce(dtp, v));
567 585 }
568 586
569 587 static int
570 588 dt_opt_runtime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
571 589 {
572 590 char *end;
573 591 dtrace_optval_t val = 0;
574 592 int i;
575 593
576 594 const struct {
577 595 char *positive;
578 596 char *negative;
579 597 } couples[] = {
580 598 { "yes", "no" },
581 599 { "enable", "disable" },
582 600 { "enabled", "disabled" },
583 601 { "true", "false" },
584 602 { "on", "off" },
585 603 { "set", "unset" },
586 604 { NULL }
587 605 };
588 606
589 607 if (arg != NULL) {
590 608 if (arg[0] == '\0') {
591 609 val = DTRACEOPT_UNSET;
592 610 goto out;
593 611 }
594 612
595 613 for (i = 0; couples[i].positive != NULL; i++) {
596 614 if (strcasecmp(couples[i].positive, arg) == 0) {
597 615 val = 1;
598 616 goto out;
599 617 }
600 618
601 619 if (strcasecmp(couples[i].negative, arg) == 0) {
602 620 val = DTRACEOPT_UNSET;
603 621 goto out;
604 622 }
605 623 }
606 624
607 625 errno = 0;
608 626 val = strtoull(arg, &end, 0);
609 627
610 628 if (*end != '\0' || errno != 0 || val < 0)
611 629 return (dt_set_errno(dtp, EDT_BADOPTVAL));
612 630 }
613 631
614 632 out:
615 633 dtp->dt_options[option] = val;
616 634 return (0);
617 635 }
618 636
619 637 static int
620 638 dt_optval_parse(const char *arg, dtrace_optval_t *rval)
621 639 {
622 640 dtrace_optval_t mul = 1;
623 641 size_t len;
624 642 char *end;
625 643
626 644 len = strlen(arg);
627 645 errno = 0;
628 646
629 647 switch (arg[len - 1]) {
630 648 case 't':
631 649 case 'T':
632 650 mul *= 1024;
633 651 /*FALLTHRU*/
634 652 case 'g':
635 653 case 'G':
636 654 mul *= 1024;
637 655 /*FALLTHRU*/
638 656 case 'm':
639 657 case 'M':
640 658 mul *= 1024;
641 659 /*FALLTHRU*/
642 660 case 'k':
643 661 case 'K':
644 662 mul *= 1024;
645 663 /*FALLTHRU*/
646 664 default:
647 665 break;
648 666 }
649 667
650 668 errno = 0;
651 669 *rval = strtoull(arg, &end, 0) * mul;
652 670
653 671 if ((mul > 1 && end != &arg[len - 1]) || (mul == 1 && *end != '\0') ||
654 672 *rval < 0 || errno != 0)
655 673 return (-1);
656 674
657 675 return (0);
658 676 }
659 677
660 678 static int
661 679 dt_opt_size(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
662 680 {
663 681 dtrace_optval_t val = 0;
664 682
665 683 if (arg != NULL && dt_optval_parse(arg, &val) != 0)
666 684 return (dt_set_errno(dtp, EDT_BADOPTVAL));
667 685
668 686 dtp->dt_options[option] = val;
669 687 return (0);
670 688 }
671 689
672 690 static int
673 691 dt_opt_rate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
674 692 {
675 693 char *end;
676 694 int i;
677 695 dtrace_optval_t mul = 1, val = 0;
678 696
679 697 const struct {
680 698 char *name;
681 699 hrtime_t mul;
682 700 } suffix[] = {
683 701 { "ns", NANOSEC / NANOSEC },
684 702 { "nsec", NANOSEC / NANOSEC },
685 703 { "us", NANOSEC / MICROSEC },
686 704 { "usec", NANOSEC / MICROSEC },
687 705 { "ms", NANOSEC / MILLISEC },
688 706 { "msec", NANOSEC / MILLISEC },
689 707 { "s", NANOSEC / SEC },
690 708 { "sec", NANOSEC / SEC },
691 709 { "m", NANOSEC * (hrtime_t)60 },
692 710 { "min", NANOSEC * (hrtime_t)60 },
693 711 { "h", NANOSEC * (hrtime_t)60 * (hrtime_t)60 },
694 712 { "hour", NANOSEC * (hrtime_t)60 * (hrtime_t)60 },
695 713 { "d", NANOSEC * (hrtime_t)(24 * 60 * 60) },
696 714 { "day", NANOSEC * (hrtime_t)(24 * 60 * 60) },
697 715 { "hz", 0 },
698 716 { NULL }
699 717 };
700 718
701 719 if (arg != NULL) {
702 720 errno = 0;
703 721 val = strtoull(arg, &end, 0);
704 722
705 723 for (i = 0; suffix[i].name != NULL; i++) {
706 724 if (strcasecmp(suffix[i].name, end) == 0) {
707 725 mul = suffix[i].mul;
708 726 break;
709 727 }
710 728 }
711 729
712 730 if (suffix[i].name == NULL && *end != '\0' || val < 0)
713 731 return (dt_set_errno(dtp, EDT_BADOPTVAL));
714 732
715 733 if (mul == 0) {
716 734 /*
717 735 * The rate has been specified in frequency-per-second.
718 736 */
719 737 if (val != 0)
720 738 val = NANOSEC / val;
721 739 } else {
722 740 val *= mul;
723 741 }
724 742 }
725 743
726 744 dtp->dt_options[option] = val;
727 745 return (0);
728 746 }
729 747
730 748 /*
731 749 * When setting the strsize option, set the option in the dt_options array
732 750 * using dt_opt_size() as usual, and then update the definition of the CTF
733 751 * type for the D intrinsic "string" to be an array of the corresponding size.
734 752 * If any errors occur, reset dt_options[option] to its previous value.
735 753 */
736 754 static int
737 755 dt_opt_strsize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
738 756 {
739 757 dtrace_optval_t val = dtp->dt_options[option];
740 758 ctf_file_t *fp = DT_STR_CTFP(dtp);
741 759 ctf_id_t type = ctf_type_resolve(fp, DT_STR_TYPE(dtp));
742 760 ctf_arinfo_t r;
743 761
744 762 if (dt_opt_size(dtp, arg, option) != 0)
745 763 return (-1); /* dt_errno is set for us */
746 764
747 765 if (dtp->dt_options[option] > UINT_MAX) {
748 766 dtp->dt_options[option] = val;
749 767 return (dt_set_errno(dtp, EOVERFLOW));
750 768 }
751 769
752 770 if (ctf_array_info(fp, type, &r) == CTF_ERR) {
753 771 dtp->dt_options[option] = val;
754 772 dtp->dt_ctferr = ctf_errno(fp);
755 773 return (dt_set_errno(dtp, EDT_CTF));
756 774 }
757 775
758 776 r.ctr_nelems = (uint_t)dtp->dt_options[option];
759 777
760 778 if (ctf_set_array(fp, type, &r) == CTF_ERR ||
761 779 ctf_update(fp) == CTF_ERR) {
762 780 dtp->dt_options[option] = val;
763 781 dtp->dt_ctferr = ctf_errno(fp);
764 782 return (dt_set_errno(dtp, EDT_CTF));
765 783 }
766 784
767 785 return (0);
768 786 }
769 787
770 788 static const struct {
771 789 const char *dtbp_name;
772 790 int dtbp_policy;
773 791 } _dtrace_bufpolicies[] = {
774 792 { "ring", DTRACEOPT_BUFPOLICY_RING },
775 793 { "fill", DTRACEOPT_BUFPOLICY_FILL },
776 794 { "switch", DTRACEOPT_BUFPOLICY_SWITCH },
777 795 { NULL, 0 }
778 796 };
779 797
780 798 /*ARGSUSED*/
781 799 static int
782 800 dt_opt_bufpolicy(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
783 801 {
784 802 dtrace_optval_t policy = DTRACEOPT_UNSET;
785 803 int i;
786 804
787 805 if (arg == NULL)
788 806 return (dt_set_errno(dtp, EDT_BADOPTVAL));
789 807
790 808 for (i = 0; _dtrace_bufpolicies[i].dtbp_name != NULL; i++) {
791 809 if (strcmp(_dtrace_bufpolicies[i].dtbp_name, arg) == 0) {
792 810 policy = _dtrace_bufpolicies[i].dtbp_policy;
793 811 break;
794 812 }
795 813 }
796 814
797 815 if (policy == DTRACEOPT_UNSET)
798 816 return (dt_set_errno(dtp, EDT_BADOPTVAL));
799 817
800 818 dtp->dt_options[DTRACEOPT_BUFPOLICY] = policy;
801 819
802 820 return (0);
803 821 }
804 822
805 823 static const struct {
806 824 const char *dtbr_name;
807 825 int dtbr_policy;
808 826 } _dtrace_bufresize[] = {
809 827 { "auto", DTRACEOPT_BUFRESIZE_AUTO },
810 828 { "manual", DTRACEOPT_BUFRESIZE_MANUAL },
811 829 { NULL, 0 }
812 830 };
813 831
814 832 /*ARGSUSED*/
815 833 static int
816 834 dt_opt_bufresize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
817 835 {
818 836 dtrace_optval_t policy = DTRACEOPT_UNSET;
819 837 int i;
820 838
821 839 if (arg == NULL)
822 840 return (dt_set_errno(dtp, EDT_BADOPTVAL));
823 841
824 842 for (i = 0; _dtrace_bufresize[i].dtbr_name != NULL; i++) {
825 843 if (strcmp(_dtrace_bufresize[i].dtbr_name, arg) == 0) {
826 844 policy = _dtrace_bufresize[i].dtbr_policy;
827 845 break;
828 846 }
829 847 }
830 848
831 849 if (policy == DTRACEOPT_UNSET)
832 850 return (dt_set_errno(dtp, EDT_BADOPTVAL));
833 851
834 852 dtp->dt_options[DTRACEOPT_BUFRESIZE] = policy;
835 853
836 854 return (0);
837 855 }
838 856
839 857 int
840 858 dt_options_load(dtrace_hdl_t *dtp)
841 859 {
842 860 dof_hdr_t hdr, *dof;
843 861 dof_sec_t *sec;
844 862 size_t offs;
845 863 int i;
846 864
847 865 /*
848 866 * To load the option values, we need to ask the kernel to provide its
849 867 * DOF, which we'll sift through to look for OPTDESC sections.
850 868 */
851 869 bzero(&hdr, sizeof (dof_hdr_t));
852 870 hdr.dofh_loadsz = sizeof (dof_hdr_t);
853 871
854 872 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &hdr) == -1)
855 873 return (dt_set_errno(dtp, errno));
856 874
857 875 if (hdr.dofh_loadsz < sizeof (dof_hdr_t))
858 876 return (dt_set_errno(dtp, EINVAL));
859 877
860 878 dof = alloca(hdr.dofh_loadsz);
861 879 bzero(dof, sizeof (dof_hdr_t));
862 880 dof->dofh_loadsz = hdr.dofh_loadsz;
863 881
864 882 for (i = 0; i < DTRACEOPT_MAX; i++)
865 883 dtp->dt_options[i] = DTRACEOPT_UNSET;
866 884
867 885 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, dof) == -1)
868 886 return (dt_set_errno(dtp, errno));
869 887
870 888 for (i = 0; i < dof->dofh_secnum; i++) {
871 889 sec = (dof_sec_t *)(uintptr_t)((uintptr_t)dof +
872 890 dof->dofh_secoff + i * dof->dofh_secsize);
873 891
874 892 if (sec->dofs_type != DOF_SECT_OPTDESC)
875 893 continue;
876 894
877 895 break;
878 896 }
879 897
880 898 for (offs = 0; offs < sec->dofs_size; offs += sec->dofs_entsize) {
881 899 dof_optdesc_t *opt = (dof_optdesc_t *)(uintptr_t)
882 900 ((uintptr_t)dof + sec->dofs_offset + offs);
883 901
884 902 if (opt->dofo_strtab != DOF_SECIDX_NONE)
885 903 continue;
886 904
887 905 if (opt->dofo_option >= DTRACEOPT_MAX)
888 906 continue;
889 907
890 908 dtp->dt_options[opt->dofo_option] = opt->dofo_value;
891 909 }
892 910
893 911 return (0);
894 912 }
895 913
896 914 typedef struct dt_option {
897 915 const char *o_name;
898 916 int (*o_func)(dtrace_hdl_t *, const char *, uintptr_t);
899 917 uintptr_t o_option;
900 918 } dt_option_t;
901 919
902 920 /*
903 921 * Compile-time options.
904 922 */
905 923 static const dt_option_t _dtrace_ctoptions[] = {
906 924 { "aggpercpu", dt_opt_agg, DTRACE_A_PERCPU },
907 925 { "amin", dt_opt_amin },
908 926 { "argref", dt_opt_cflags, DTRACE_C_ARGREF },
909 927 { "core", dt_opt_core },
↓ open down ↓ |
561 lines elided |
↑ open up ↑ |
910 928 { "cpp", dt_opt_cflags, DTRACE_C_CPP },
911 929 { "cpphdrs", dt_opt_cpp_hdrs },
912 930 { "cpppath", dt_opt_cpp_path },
913 931 { "ctypes", dt_opt_ctypes },
914 932 { "defaultargs", dt_opt_cflags, DTRACE_C_DEFARG },
915 933 { "dtypes", dt_opt_dtypes },
916 934 { "debug", dt_opt_debug },
917 935 { "define", dt_opt_cpp_opts, (uintptr_t)"-D" },
918 936 { "droptags", dt_opt_droptags },
919 937 { "empty", dt_opt_cflags, DTRACE_C_EMPTY },
938 + { "encoding", dt_opt_encoding },
920 939 { "errtags", dt_opt_cflags, DTRACE_C_ETAGS },
921 940 { "evaltime", dt_opt_evaltime },
922 941 { "incdir", dt_opt_cpp_opts, (uintptr_t)"-I" },
923 942 { "iregs", dt_opt_iregs },
924 943 { "kdefs", dt_opt_invcflags, DTRACE_C_KNODEF },
925 944 { "knodefs", dt_opt_cflags, DTRACE_C_KNODEF },
926 945 { "late", dt_opt_xlate },
927 946 { "lazyload", dt_opt_lazyload },
928 947 { "ldpath", dt_opt_ld_path },
929 948 { "libdir", dt_opt_libdir },
930 949 { "linkmode", dt_opt_linkmode },
931 950 { "linktype", dt_opt_linktype },
932 951 { "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS },
933 952 { "pgmax", dt_opt_pgmax },
934 953 { "pspec", dt_opt_cflags, DTRACE_C_PSPEC },
935 954 { "setenv", dt_opt_setenv, 1 },
936 955 { "stdc", dt_opt_stdc },
937 956 { "strip", dt_opt_dflags, DTRACE_D_STRIP },
938 957 { "syslibdir", dt_opt_syslibdir },
939 958 { "tree", dt_opt_tree },
940 959 { "tregs", dt_opt_tregs },
941 960 { "udefs", dt_opt_invcflags, DTRACE_C_UNODEF },
942 961 { "undef", dt_opt_cpp_opts, (uintptr_t)"-U" },
943 962 { "unodefs", dt_opt_cflags, DTRACE_C_UNODEF },
944 963 { "unsetenv", dt_opt_setenv, 0 },
945 964 { "verbose", dt_opt_cflags, DTRACE_C_DIFV },
946 965 { "version", dt_opt_version },
947 966 { "zdefs", dt_opt_cflags, DTRACE_C_ZDEFS },
948 967 { NULL }
949 968 };
950 969
951 970 /*
952 971 * Run-time options.
953 972 */
954 973 static const dt_option_t _dtrace_rtoptions[] = {
955 974 { "aggsize", dt_opt_size, DTRACEOPT_AGGSIZE },
956 975 { "bufsize", dt_opt_size, DTRACEOPT_BUFSIZE },
957 976 { "bufpolicy", dt_opt_bufpolicy, DTRACEOPT_BUFPOLICY },
958 977 { "bufresize", dt_opt_bufresize, DTRACEOPT_BUFRESIZE },
959 978 { "cleanrate", dt_opt_rate, DTRACEOPT_CLEANRATE },
960 979 { "cpu", dt_opt_runtime, DTRACEOPT_CPU },
961 980 { "destructive", dt_opt_runtime, DTRACEOPT_DESTRUCTIVE },
962 981 { "dynvarsize", dt_opt_size, DTRACEOPT_DYNVARSIZE },
963 982 { "grabanon", dt_opt_runtime, DTRACEOPT_GRABANON },
964 983 { "jstackframes", dt_opt_runtime, DTRACEOPT_JSTACKFRAMES },
965 984 { "jstackstrsize", dt_opt_size, DTRACEOPT_JSTACKSTRSIZE },
966 985 { "nspec", dt_opt_runtime, DTRACEOPT_NSPEC },
967 986 { "specsize", dt_opt_size, DTRACEOPT_SPECSIZE },
968 987 { "stackframes", dt_opt_runtime, DTRACEOPT_STACKFRAMES },
969 988 { "statusrate", dt_opt_rate, DTRACEOPT_STATUSRATE },
↓ open down ↓ |
40 lines elided |
↑ open up ↑ |
970 989 { "strsize", dt_opt_strsize, DTRACEOPT_STRSIZE },
971 990 { "ustackframes", dt_opt_runtime, DTRACEOPT_USTACKFRAMES },
972 991 { "temporal", dt_opt_runtime, DTRACEOPT_TEMPORAL },
973 992 { NULL }
974 993 };
975 994
976 995 /*
977 996 * Dynamic run-time options.
978 997 */
979 998 static const dt_option_t _dtrace_drtoptions[] = {
999 + { "agghist", dt_opt_runtime, DTRACEOPT_AGGHIST },
1000 + { "aggpack", dt_opt_runtime, DTRACEOPT_AGGPACK },
980 1001 { "aggrate", dt_opt_rate, DTRACEOPT_AGGRATE },
981 1002 { "aggsortkey", dt_opt_runtime, DTRACEOPT_AGGSORTKEY },
982 1003 { "aggsortkeypos", dt_opt_runtime, DTRACEOPT_AGGSORTKEYPOS },
983 1004 { "aggsortpos", dt_opt_runtime, DTRACEOPT_AGGSORTPOS },
984 1005 { "aggsortrev", dt_opt_runtime, DTRACEOPT_AGGSORTREV },
1006 + { "aggzoom", dt_opt_runtime, DTRACEOPT_AGGZOOM },
985 1007 { "flowindent", dt_opt_runtime, DTRACEOPT_FLOWINDENT },
986 1008 { "quiet", dt_opt_runtime, DTRACEOPT_QUIET },
987 1009 { "rawbytes", dt_opt_runtime, DTRACEOPT_RAWBYTES },
988 1010 { "stackindent", dt_opt_runtime, DTRACEOPT_STACKINDENT },
989 1011 { "switchrate", dt_opt_rate, DTRACEOPT_SWITCHRATE },
990 1012 { NULL }
991 1013 };
992 1014
993 1015 int
994 1016 dtrace_getopt(dtrace_hdl_t *dtp, const char *opt, dtrace_optval_t *val)
995 1017 {
996 1018 const dt_option_t *op;
997 1019
998 1020 if (opt == NULL)
999 1021 return (dt_set_errno(dtp, EINVAL));
1000 1022
1001 1023 /*
1002 1024 * We only need to search the run-time options -- it's not legal
1003 1025 * to get the values of compile-time options.
1004 1026 */
1005 1027 for (op = _dtrace_rtoptions; op->o_name != NULL; op++) {
1006 1028 if (strcmp(op->o_name, opt) == 0) {
1007 1029 *val = dtp->dt_options[op->o_option];
1008 1030 return (0);
1009 1031 }
1010 1032 }
1011 1033
1012 1034 for (op = _dtrace_drtoptions; op->o_name != NULL; op++) {
1013 1035 if (strcmp(op->o_name, opt) == 0) {
1014 1036 *val = dtp->dt_options[op->o_option];
1015 1037 return (0);
1016 1038 }
1017 1039 }
1018 1040
1019 1041 return (dt_set_errno(dtp, EDT_BADOPTNAME));
1020 1042 }
1021 1043
1022 1044 int
1023 1045 dtrace_setopt(dtrace_hdl_t *dtp, const char *opt, const char *val)
1024 1046 {
1025 1047 const dt_option_t *op;
1026 1048
1027 1049 if (opt == NULL)
1028 1050 return (dt_set_errno(dtp, EINVAL));
1029 1051
1030 1052 for (op = _dtrace_ctoptions; op->o_name != NULL; op++) {
1031 1053 if (strcmp(op->o_name, opt) == 0)
1032 1054 return (op->o_func(dtp, val, op->o_option));
1033 1055 }
1034 1056
1035 1057 for (op = _dtrace_drtoptions; op->o_name != NULL; op++) {
1036 1058 if (strcmp(op->o_name, opt) == 0)
1037 1059 return (op->o_func(dtp, val, op->o_option));
1038 1060 }
1039 1061
1040 1062 for (op = _dtrace_rtoptions; op->o_name != NULL; op++) {
1041 1063 if (strcmp(op->o_name, opt) == 0) {
1042 1064 /*
1043 1065 * Only dynamic run-time options may be set while
1044 1066 * tracing is active.
1045 1067 */
1046 1068 if (dtp->dt_active)
1047 1069 return (dt_set_errno(dtp, EDT_ACTIVE));
1048 1070
1049 1071 return (op->o_func(dtp, val, op->o_option));
1050 1072 }
1051 1073 }
1052 1074
1053 1075 return (dt_set_errno(dtp, EDT_BADOPTNAME));
1054 1076 }
↓ open down ↓ |
60 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX