1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 3235 raf * Common Development and Distribution License (the "License"). 6 3235 raf * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 3235 raf 22 0 stevel /* 23 5891 raf * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 0 stevel * Use is subject to license terms. 25 0 stevel */ 26 0 stevel 27 0 stevel /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 0 stevel /* All Rights Reserved */ 29 0 stevel 30 0 stevel #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.2 */ 31 0 stevel 32 0 stevel #include <stdio.h> 33 0 stevel #include <stdlib.h> 34 0 stevel #include <unistd.h> 35 0 stevel #include <ctype.h> 36 0 stevel #include <string.h> 37 0 stevel #include <memory.h> 38 0 stevel #include <sys/types.h> 39 0 stevel #include <signal.h> 40 0 stevel #include <libproc.h> 41 0 stevel #include "ramdata.h" 42 0 stevel #include "systable.h" 43 0 stevel #include "proto.h" 44 0 stevel 45 0 stevel /* XXX A bug in the <string.h> header file requires this */ 46 0 stevel extern char *strtok_r(char *s1, const char *s2, char **lasts); 47 0 stevel 48 0 stevel /* 49 0 stevel * option procesing --- 50 0 stevel * Routines for scanning syscall, signal, fault 51 0 stevel * and file descriptor lists. 52 0 stevel */ 53 0 stevel 54 0 stevel /* 55 0 stevel * Function prototypes for static routines in this module. 56 0 stevel */ 57 0 stevel void upcase(char *); 58 0 stevel 59 0 stevel const char white[] = " \t\n"; /* white space characters */ 60 0 stevel const char sepr[] = " ,\t\n"; /* list separator characters */ 61 0 stevel const char csepr[] = " :,\t\n"; /* same, with ':' added */ 62 0 stevel 63 0 stevel /* 64 0 stevel * Scan list of syscall names. 65 0 stevel * Return 0 on success, != 0 on any failure. 66 0 stevel */ 67 0 stevel int 68 0 stevel syslist(char *str, /* string of syscall names */ 69 0 stevel sysset_t *setp, /* syscall set */ 70 0 stevel int *fp) /* first-time flag */ 71 0 stevel { 72 0 stevel char *name; 73 0 stevel int exclude = FALSE; 74 0 stevel int rc = 0; 75 0 stevel char *lasts; 76 0 stevel 77 0 stevel name = strtok_r(str, sepr, &lasts); 78 0 stevel 79 0 stevel if (name != NULL && *name == '!') { /* exclude from set */ 80 0 stevel exclude = TRUE; 81 0 stevel if (*++name == '\0') 82 0 stevel name = strtok_r(NULL, sepr, &lasts); 83 0 stevel } else if (!*fp) { /* first time, clear the set */ 84 0 stevel premptyset(setp); 85 0 stevel *fp = TRUE; 86 0 stevel } 87 0 stevel 88 0 stevel for (; name; name = strtok_r(NULL, sepr, &lasts)) { 89 0 stevel int sys; 90 0 stevel int sysx; 91 3235 raf int sysxx; 92 0 stevel int sys64; 93 0 stevel char *next; 94 0 stevel 95 0 stevel if (*name == '!') { /* exclude remainder from set */ 96 0 stevel exclude = TRUE; 97 0 stevel while (*++name == '!') 98 0 stevel /* empty */; 99 0 stevel if (*name == '\0') 100 0 stevel continue; 101 0 stevel } 102 0 stevel 103 0 stevel sys = strtol(name, &next, 0); 104 3235 raf sysx = sysxx = sys64 = 0; 105 0 stevel if (sys < 0 || sys > PRMAXSYS || *next != '\0') 106 0 stevel sys = 0; 107 0 stevel if (sys == 0) { 108 0 stevel const struct systable *stp = systable; 109 0 stevel for (; sys == 0 && stp->nargs >= 0; stp++) 110 0 stevel if (stp->name && strcmp(stp->name, name) == 0) 111 0 stevel sys = stp-systable; 112 0 stevel } 113 0 stevel if (sys == 0) { 114 0 stevel const struct sysalias *sap = sysalias; 115 0 stevel for (; sys == 0 && sap->name; sap++) 116 0 stevel if (strcmp(sap->name, name) == 0) 117 0 stevel sys = sap->number; 118 0 stevel } 119 0 stevel if (sys > 0 && sys <= PRMAXSYS) { 120 0 stevel switch (sys) { 121 0 stevel case SYS_xstat: /* set all if any */ 122 0 stevel case SYS_stat: 123 0 stevel case SYS_stat64: 124 0 stevel sys = SYS_stat; 125 0 stevel sysx = SYS_xstat; 126 0 stevel sys64 = SYS_stat64; 127 0 stevel goto def; 128 0 stevel 129 0 stevel case SYS_lxstat: /* set all if any */ 130 0 stevel case SYS_lstat: 131 0 stevel case SYS_lstat64: 132 0 stevel sys = SYS_lstat; 133 0 stevel sysx = SYS_lxstat; 134 0 stevel sys64 = SYS_lstat64; 135 0 stevel goto def; 136 0 stevel 137 0 stevel case SYS_fxstat: /* set all if any */ 138 0 stevel case SYS_fstat: 139 0 stevel case SYS_fstat64: 140 0 stevel sys = SYS_fstat; 141 0 stevel sysx = SYS_fxstat; 142 0 stevel sys64 = SYS_fstat64; 143 0 stevel goto def; 144 0 stevel 145 0 stevel case SYS_getdents: /* set both if either */ 146 0 stevel case SYS_getdents64: 147 0 stevel sys = SYS_getdents; 148 0 stevel sys64 = SYS_getdents64; 149 0 stevel goto def; 150 0 stevel 151 0 stevel case SYS_mmap: /* set both if either */ 152 0 stevel case SYS_mmap64: 153 0 stevel sys = SYS_mmap; 154 0 stevel sys64 = SYS_mmap64; 155 0 stevel goto def; 156 0 stevel 157 0 stevel case SYS_statvfs: /* set both if either */ 158 0 stevel case SYS_statvfs64: 159 0 stevel sys = SYS_statvfs; 160 0 stevel sys64 = SYS_statvfs64; 161 0 stevel goto def; 162 0 stevel 163 0 stevel case SYS_fstatvfs: /* set both if either */ 164 0 stevel case SYS_fstatvfs64: 165 0 stevel sys = SYS_fstatvfs; 166 0 stevel sys64 = SYS_fstatvfs64; 167 0 stevel goto def; 168 0 stevel 169 0 stevel case SYS_setrlimit: /* set both if either */ 170 0 stevel case SYS_setrlimit64: 171 0 stevel sys = SYS_setrlimit; 172 0 stevel sys64 = SYS_setrlimit64; 173 0 stevel goto def; 174 0 stevel 175 0 stevel case SYS_getrlimit: /* set both if either */ 176 0 stevel case SYS_getrlimit64: 177 0 stevel sys = SYS_getrlimit; 178 0 stevel sys64 = SYS_getrlimit64; 179 0 stevel goto def; 180 0 stevel 181 0 stevel case SYS_pread: /* set both if either */ 182 0 stevel case SYS_pread64: 183 0 stevel sys = SYS_pread; 184 0 stevel sys64 = SYS_pread64; 185 0 stevel goto def; 186 0 stevel 187 0 stevel case SYS_pwrite: /* set both if either */ 188 0 stevel case SYS_pwrite64: 189 0 stevel sys = SYS_pwrite; 190 0 stevel sys64 = SYS_pwrite64; 191 0 stevel goto def; 192 0 stevel 193 0 stevel case SYS_creat: /* set both if either */ 194 0 stevel case SYS_creat64: 195 0 stevel sys = SYS_creat; 196 0 stevel sys64 = SYS_creat64; 197 0 stevel goto def; 198 0 stevel 199 0 stevel case SYS_open: /* set both if either */ 200 0 stevel case SYS_open64: 201 0 stevel sys = SYS_open; 202 0 stevel sys64 = SYS_open64; 203 0 stevel goto def; 204 0 stevel 205 0 stevel case SYS_xmknod: /* set both if either */ 206 0 stevel case SYS_mknod: 207 0 stevel sysx = SYS_xmknod; 208 0 stevel sys = SYS_mknod; 209 0 stevel goto def; 210 0 stevel 211 0 stevel case SYS_forkall: /* set all if any */ 212 0 stevel case SYS_fork1: 213 0 stevel case SYS_vfork: 214 3235 raf case SYS_forksys: 215 0 stevel sys = SYS_forkall; 216 0 stevel sysx = SYS_fork1; 217 0 stevel sys64 = SYS_vfork; 218 3235 raf sysxx = SYS_forksys; 219 0 stevel goto def; 220 0 stevel 221 0 stevel case SYS_exec: /* set both if either */ 222 0 stevel case SYS_execve: 223 0 stevel sysx = SYS_exec; 224 0 stevel sys = SYS_execve; 225 0 stevel goto def; 226 0 stevel 227 0 stevel case SYS_poll: /* set both if either */ 228 0 stevel case SYS_pollsys: 229 0 stevel sysx = SYS_poll; 230 0 stevel sys = SYS_pollsys; 231 0 stevel goto def; 232 0 stevel 233 0 stevel case SYS_sigprocmask: /* set both if either */ 234 0 stevel case SYS_lwp_sigmask: 235 0 stevel sysx = SYS_sigprocmask; 236 0 stevel sys = SYS_lwp_sigmask; 237 0 stevel goto def; 238 0 stevel 239 0 stevel case SYS_wait: /* set both if either */ 240 5891 raf case SYS_waitid: 241 0 stevel sysx = SYS_wait; 242 5891 raf sys = SYS_waitid; 243 0 stevel goto def; 244 0 stevel 245 0 stevel case SYS_lseek: /* set both if either */ 246 0 stevel case SYS_llseek: 247 0 stevel sysx = SYS_lseek; 248 0 stevel sys = SYS_llseek; 249 0 stevel goto def; 250 0 stevel 251 0 stevel case SYS_lwp_mutex_lock: /* set both if either */ 252 0 stevel case SYS_lwp_mutex_timedlock: 253 0 stevel sysx = SYS_lwp_mutex_lock; 254 0 stevel sys = SYS_lwp_mutex_timedlock; 255 0 stevel goto def; 256 0 stevel 257 0 stevel case SYS_lwp_sema_wait: /* set both if either */ 258 0 stevel case SYS_lwp_sema_timedwait: 259 0 stevel sysx = SYS_lwp_sema_wait; 260 0 stevel sys = SYS_lwp_sema_timedwait; 261 0 stevel goto def; 262 0 stevel 263 0 stevel default: 264 0 stevel def: 265 0 stevel if (exclude) { 266 0 stevel prdelset(setp, sys); 267 0 stevel if (sysx) 268 0 stevel prdelset(setp, sysx); 269 3235 raf if (sysxx) 270 3235 raf prdelset(setp, sysxx); 271 0 stevel if (sys64) 272 0 stevel prdelset(setp, sys64); 273 0 stevel } else { 274 0 stevel praddset(setp, sys); 275 0 stevel if (sysx) 276 0 stevel praddset(setp, sysx); 277 3235 raf if (sysxx) 278 3235 raf praddset(setp, sysxx); 279 0 stevel if (sys64) 280 0 stevel praddset(setp, sys64); 281 0 stevel } 282 0 stevel break; 283 0 stevel } 284 0 stevel } else if (strcmp(name, "all") == 0 || 285 0 stevel strcmp(name, "ALL") == 0) { 286 0 stevel if (exclude) { 287 0 stevel premptyset(setp); 288 0 stevel } else { 289 0 stevel prfillset(setp); 290 0 stevel } 291 0 stevel } else { 292 0 stevel (void) fprintf(stderr, 293 5891 raf "%s: unrecognized syscall: %s\n", 294 5891 raf command, name); 295 0 stevel rc = -1; 296 0 stevel } 297 0 stevel } 298 0 stevel 299 0 stevel return (rc); 300 0 stevel } 301 0 stevel 302 0 stevel /* 303 0 stevel * List of signals to trace. 304 0 stevel * Return 0 on success, != 0 on any failure. 305 0 stevel */ 306 0 stevel int 307 0 stevel siglist(private_t *pri, 308 0 stevel char *str, /* string of signal names */ 309 0 stevel sigset_t *setp, /* signal set */ 310 0 stevel int *fp) /* first-time flag */ 311 0 stevel { 312 0 stevel char *name; 313 0 stevel int exclude = FALSE; 314 0 stevel int rc = 0; 315 0 stevel char *lasts; 316 0 stevel 317 0 stevel upcase(str); 318 0 stevel name = strtok_r(str, sepr, &lasts); 319 0 stevel 320 0 stevel if (name != NULL && *name == '!') { /* exclude from set */ 321 0 stevel exclude = TRUE; 322 0 stevel if (*++name == '\0') 323 0 stevel name = strtok_r(NULL, sepr, &lasts); 324 0 stevel } else if (!*fp) { /* first time, clear the set */ 325 0 stevel premptyset(setp); 326 0 stevel *fp = TRUE; 327 0 stevel } 328 0 stevel 329 0 stevel for (; name; name = strtok_r(NULL, sepr, &lasts)) { 330 0 stevel int sig; 331 0 stevel char *next; 332 0 stevel 333 0 stevel if (*name == '!') { /* exclude remainder from set */ 334 0 stevel exclude = TRUE; 335 0 stevel while (*++name == '!') 336 0 stevel /* empty */; 337 0 stevel if (*name == '\0') 338 0 stevel continue; 339 0 stevel } 340 0 stevel 341 0 stevel sig = strtol(name, &next, 0); 342 0 stevel if (sig <= 0 || sig > PRMAXSIG || *next != '\0') { 343 0 stevel for (sig = 1; sig <= PRMAXSIG; sig++) { 344 0 stevel const char *sname = rawsigname(pri, sig); 345 0 stevel if (sname == NULL) 346 0 stevel continue; 347 0 stevel if (strcmp(sname, name) == 0 || 348 0 stevel strcmp(sname+3, name) == 0) 349 0 stevel break; 350 0 stevel } 351 0 stevel if (sig > PRMAXSIG) 352 0 stevel sig = 0; 353 0 stevel } 354 0 stevel if (sig > 0 && sig <= PRMAXSIG) { 355 0 stevel if (exclude) { 356 0 stevel prdelset(setp, sig); 357 0 stevel } else { 358 0 stevel praddset(setp, sig); 359 0 stevel } 360 0 stevel } else if (strcmp(name, "ALL") == 0) { 361 0 stevel if (exclude) { 362 0 stevel premptyset(setp); 363 0 stevel } else { 364 0 stevel prfillset(setp); 365 0 stevel } 366 0 stevel } else { 367 0 stevel (void) fprintf(stderr, 368 5891 raf "%s: unrecognized signal name/number: %s\n", 369 5891 raf command, name); 370 0 stevel rc = -1; 371 0 stevel } 372 0 stevel } 373 0 stevel 374 0 stevel return (rc); 375 0 stevel } 376 0 stevel 377 0 stevel /* 378 0 stevel * List of faults to trace. 379 0 stevel * return 0 on success, != 0 on any failure. 380 0 stevel */ 381 0 stevel int 382 0 stevel fltlist(char *str, /* string of fault names */ 383 0 stevel fltset_t *setp, /* fault set */ 384 0 stevel int *fp) /* first-time flag */ 385 0 stevel { 386 0 stevel char *name; 387 0 stevel int exclude = FALSE; 388 0 stevel int rc = 0; 389 0 stevel char *lasts; 390 0 stevel 391 0 stevel upcase(str); 392 0 stevel name = strtok_r(str, sepr, &lasts); 393 0 stevel 394 0 stevel if (name != NULL && *name == '!') { /* exclude from set */ 395 0 stevel exclude = TRUE; 396 0 stevel if (*++name == '\0') 397 0 stevel name = strtok_r(NULL, sepr, &lasts); 398 0 stevel } else if (!*fp) { /* first time, clear the set */ 399 0 stevel premptyset(setp); 400 0 stevel *fp = TRUE; 401 0 stevel } 402 0 stevel 403 0 stevel for (; name; name = strtok_r(NULL, sepr, &lasts)) { 404 0 stevel int flt; 405 0 stevel char *next; 406 0 stevel 407 0 stevel if (*name == '!') { /* exclude remainder from set */ 408 0 stevel exclude = TRUE; 409 0 stevel while (*++name == '!') 410 0 stevel /* empty */; 411 0 stevel if (*name == '\0') 412 0 stevel continue; 413 0 stevel } 414 0 stevel 415 0 stevel flt = strtol(name, &next, 0); 416 0 stevel if (flt <= 0 || flt > PRMAXFAULT || *next != '\0') { 417 0 stevel for (flt = 1; flt <= PRMAXFAULT; flt++) { 418 0 stevel char fname[32]; 419 0 stevel 420 0 stevel if (proc_fltname(flt, fname, 421 0 stevel sizeof (fname)) == NULL) 422 0 stevel continue; 423 0 stevel 424 0 stevel if (strcmp(fname, name) == 0 || 425 0 stevel strcmp(fname+3, name) == 0) 426 0 stevel break; 427 0 stevel } 428 0 stevel if (flt > PRMAXFAULT) 429 0 stevel flt = 0; 430 0 stevel } 431 0 stevel if (flt > 0 && flt <= PRMAXFAULT) { 432 0 stevel if (exclude) { 433 0 stevel prdelset(setp, flt); 434 0 stevel } else { 435 0 stevel praddset(setp, flt); 436 0 stevel } 437 0 stevel } else if (strcmp(name, "ALL") == 0) { 438 0 stevel if (exclude) { 439 0 stevel premptyset(setp); 440 0 stevel } else { 441 0 stevel prfillset(setp); 442 0 stevel } 443 0 stevel } else { 444 0 stevel (void) fprintf(stderr, 445 5891 raf "%s: unrecognized fault name/number: %s\n", 446 5891 raf command, name); 447 0 stevel rc = -1; 448 0 stevel } 449 0 stevel } 450 0 stevel 451 0 stevel return (rc); 452 0 stevel } 453 0 stevel 454 0 stevel /* 455 0 stevel * Gather file descriptors to dump. 456 0 stevel * Return 0 on success, != 0 on any failure. 457 0 stevel */ 458 0 stevel int 459 0 stevel fdlist(char *str, /* string of filedescriptors */ 460 0 stevel fileset_t *setp) /* set of boolean flags */ 461 0 stevel { 462 0 stevel char *name; 463 0 stevel int exclude = FALSE; 464 0 stevel int rc = 0; 465 0 stevel char *lasts; 466 0 stevel 467 0 stevel upcase(str); 468 0 stevel name = strtok_r(str, sepr, &lasts); 469 0 stevel 470 0 stevel if (name != NULL && *name == '!') { /* exclude from set */ 471 0 stevel exclude = TRUE; 472 0 stevel if (*++name == '\0') 473 0 stevel name = strtok_r(NULL, sepr, &lasts); 474 0 stevel } 475 0 stevel 476 0 stevel for (; name; name = strtok_r(NULL, sepr, &lasts)) { 477 0 stevel int fd; 478 0 stevel char *next; 479 0 stevel 480 0 stevel if (*name == '!') { /* exclude remainder from set */ 481 0 stevel exclude = TRUE; 482 0 stevel while (*++name == '!') 483 0 stevel /* empty */; 484 0 stevel if (*name == '\0') 485 0 stevel continue; 486 0 stevel } 487 0 stevel 488 0 stevel fd = strtol(name, &next, 0); 489 0 stevel if (fd >= 0 && fd < NOFILES_MAX && *next == '\0') { 490 0 stevel fd++; 491 0 stevel if (exclude) { 492 0 stevel prdelset(setp, fd); 493 0 stevel } else { 494 0 stevel praddset(setp, fd); 495 0 stevel } 496 0 stevel } else if (strcmp(name, "ALL") == 0) { 497 0 stevel if (exclude) { 498 0 stevel premptyset(setp); 499 0 stevel } else { 500 0 stevel prfillset(setp); 501 0 stevel } 502 0 stevel } else { 503 0 stevel (void) fprintf(stderr, 504 5891 raf "%s: filedescriptor not in range[0..%d]: %s\n", 505 5891 raf command, NOFILES_MAX-1, name); 506 0 stevel rc = -1; 507 0 stevel } 508 0 stevel } 509 0 stevel 510 0 stevel return (rc); 511 0 stevel } 512 0 stevel 513 0 stevel void 514 0 stevel upcase(char *str) 515 0 stevel { 516 0 stevel int c; 517 0 stevel 518 0 stevel while ((c = *str) != '\0') 519 0 stevel *str++ = toupper(c); 520 0 stevel } 521 0 stevel 522 0 stevel /* 523 0 stevel * 'arg' points to a string like: 524 0 stevel * libc,libnsl,... : printf,read,write,... 525 0 stevel * or 526 0 stevel * libc,libnsl,... :: printf,read,write,... 527 0 stevel * with possible filename pattern-matching metacharacters. 528 0 stevel * 529 0 stevel * Assumption: No library or function name can contain ',' or ':'. 530 0 stevel */ 531 0 stevel int 532 0 stevel liblist(char *arg, int hang) 533 0 stevel { 534 0 stevel const char *star = "*"; 535 0 stevel struct dynpat *Dyp; 536 0 stevel char *pat; 537 0 stevel char *fpat; 538 0 stevel char *lasts; 539 0 stevel uint_t maxpat; 540 0 stevel 541 0 stevel /* append a new dynpat structure to the end of the Dynpat list */ 542 0 stevel Dyp = my_malloc(sizeof (struct dynpat), NULL); 543 0 stevel Dyp->next = NULL; 544 0 stevel if (Lastpat == NULL) 545 0 stevel Dynpat = Lastpat = Dyp; 546 0 stevel else { 547 0 stevel Lastpat->next = Dyp; 548 0 stevel Lastpat = Dyp; 549 0 stevel } 550 0 stevel Dyp->flag = hang? BPT_HANG : 0; 551 0 stevel Dyp->exclude_lib = 0; 552 0 stevel Dyp->exclude = 0; 553 0 stevel Dyp->internal = 0; 554 0 stevel Dyp->Dp = NULL; 555 0 stevel 556 0 stevel /* 557 0 stevel * Find the beginning of the filename patterns 558 0 stevel * and null-terminate the library name patterns. 559 0 stevel */ 560 0 stevel if ((fpat = strchr(arg, ':')) != NULL) 561 0 stevel *fpat++ = '\0'; 562 0 stevel 563 0 stevel /* 564 0 stevel * Library name patterns. 565 0 stevel */ 566 0 stevel pat = strtok_r(arg, sepr, &lasts); 567 0 stevel 568 0 stevel /* '!' introduces an exclusion list */ 569 0 stevel if (pat != NULL && *pat == '!') { 570 0 stevel Dyp->exclude_lib = 1; 571 0 stevel pat += strspn(pat, "!"); 572 0 stevel if (*pat == '\0') 573 0 stevel pat = strtok_r(NULL, sepr, &lasts); 574 0 stevel /* force exclusion of all functions as well */ 575 0 stevel Dyp->exclude = 1; 576 0 stevel Dyp->internal = 1; 577 0 stevel fpat = NULL; 578 0 stevel } 579 0 stevel 580 0 stevel if (pat == NULL) { 581 0 stevel /* empty list means all libraries */ 582 0 stevel Dyp->libpat = my_malloc(sizeof (char *), NULL); 583 0 stevel Dyp->libpat[0] = star; 584 0 stevel Dyp->nlibpat = 1; 585 0 stevel } else { 586 0 stevel /* 587 0 stevel * We are now at the library list. 588 0 stevel * Generate the list and count the library name patterns. 589 0 stevel */ 590 0 stevel maxpat = 1; 591 0 stevel Dyp->libpat = my_malloc(maxpat * sizeof (char *), NULL); 592 0 stevel Dyp->nlibpat = 0; 593 0 stevel Dyp->libpat[Dyp->nlibpat++] = pat; 594 0 stevel while ((pat = strtok_r(NULL, sepr, &lasts)) != NULL) { 595 0 stevel if (Dyp->nlibpat == maxpat) { 596 0 stevel maxpat *= 2; 597 0 stevel Dyp->libpat = my_realloc(Dyp->libpat, 598 5891 raf maxpat * sizeof (char *), NULL); 599 0 stevel } 600 0 stevel Dyp->libpat[Dyp->nlibpat++] = pat; 601 0 stevel } 602 0 stevel } 603 0 stevel 604 0 stevel /* 605 0 stevel * Function name patterns. 606 0 stevel */ 607 0 stevel if (fpat == NULL) 608 0 stevel pat = NULL; 609 0 stevel else { 610 0 stevel /* 611 0 stevel * We have already seen a ':'. Look for another. 612 0 stevel * Double ':' means trace internal calls. 613 0 stevel */ 614 0 stevel fpat += strspn(fpat, white); 615 0 stevel if (*fpat == ':') { 616 0 stevel Dyp->internal = 1; 617 0 stevel *fpat++ = '\0'; 618 0 stevel } 619 0 stevel pat = strtok_r(fpat, csepr, &lasts); 620 0 stevel } 621 0 stevel 622 0 stevel /* '!' introduces an exclusion list */ 623 0 stevel if (pat != NULL && *pat == '!') { 624 0 stevel Dyp->exclude = 1; 625 0 stevel Dyp->internal = 1; 626 0 stevel pat += strspn(pat, "!"); 627 0 stevel if (*pat == '\0') 628 0 stevel pat = strtok_r(NULL, sepr, &lasts); 629 0 stevel } 630 0 stevel 631 0 stevel if (pat == NULL) { 632 0 stevel /* empty function list means exclude all functions */ 633 0 stevel Dyp->sympat = my_malloc(sizeof (char *), NULL); 634 0 stevel Dyp->sympat[0] = star; 635 0 stevel Dyp->nsympat = 1; 636 0 stevel } else { 637 0 stevel /* 638 0 stevel * We are now at the function list. 639 0 stevel * Generate the list and count the symbol name patterns. 640 0 stevel */ 641 0 stevel maxpat = 1; 642 0 stevel Dyp->sympat = my_malloc(maxpat * sizeof (char *), NULL); 643 0 stevel Dyp->nsympat = 0; 644 0 stevel Dyp->sympat[Dyp->nsympat++] = pat; 645 0 stevel while ((pat = strtok_r(NULL, sepr, &lasts)) != NULL) { 646 0 stevel if (Dyp->nsympat == maxpat) { 647 0 stevel maxpat *= 2; 648 0 stevel Dyp->sympat = my_realloc(Dyp->sympat, 649 5891 raf maxpat * sizeof (char *), NULL); 650 0 stevel } 651 0 stevel Dyp->sympat[Dyp->nsympat++] = pat; 652 0 stevel } 653 0 stevel } 654 0 stevel 655 0 stevel return (0); 656 0 stevel } 657