1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 /* Copyright (c) 1988 AT&T */ 27 /* All Rights Reserved */ 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <unistd.h> 32 #include <ctype.h> 33 #include <string.h> 34 #include <memory.h> 35 #include <errno.h> 36 #include <limits.h> 37 #include <sys/types.h> 38 #include <sys/stack.h> 39 #include <signal.h> 40 #include <sys/isa_defs.h> 41 #include <libproc.h> 42 #include <priv.h> 43 #include "ramdata.h" 44 #include "systable.h" 45 #include "print.h" 46 #include "proto.h" 47 48 /* 49 * Actions to take when process stops. 50 */ 51 52 /* 53 * Function prototypes for static routines in this module. 54 */ 55 int stopsig(private_t *); 56 void showpaths(private_t *, const struct systable *); 57 void showargs(private_t *, int); 58 void dumpargs(private_t *, long, const char *); 59 60 /* 61 * Report an lwp to be sleeping (if true). 62 */ 63 void 64 report_sleeping(private_t *pri, int dotrace) 65 { 66 const lwpstatus_t *Lsp = pri->lwpstat; 67 int sys = Lsp->pr_syscall; 68 69 if (!prismember(&trace, sys) || !dotrace || 70 !(Lsp->pr_flags & (PR_ASLEEP|PR_VFORKP))) { 71 /* Make sure we catch sysexit even if we're not tracing it. */ 72 (void) Psysexit(Proc, sys, TRUE); 73 return; 74 } 75 76 pri->length = 0; 77 pri->Errno = 0; 78 pri->ErrPriv = PRIV_NONE; 79 pri->Rval1 = pri->Rval2 = 0; 80 (void) sysentry(pri, dotrace); 81 make_pname(pri, 0); 82 putpname(pri); 83 timestamp(pri); 84 pri->length += printf("%s", pri->sys_string); 85 pri->sys_leng = 0; 86 *pri->sys_string = '\0'; 87 pri->length >>= 3; 88 if (Lsp->pr_flags & PR_VFORKP) 89 pri->length += 2; 90 if (pri->length >= 4) 91 (void) fputc(' ', stdout); 92 for (; pri->length < 4; pri->length++) 93 (void) fputc('\t', stdout); 94 if (Lsp->pr_flags & PR_VFORKP) 95 (void) fputs("(waiting for child to exit()/exec()...)\n", 96 stdout); 97 else 98 (void) fputs("(sleeping...)\n", stdout); 99 pri->length = 0; 100 if (prismember(&verbose, sys)) { 101 int raw = prismember(&rawout, sys); 102 pri->Errno = 1; 103 expound(pri, 0, raw); 104 pri->Errno = 0; 105 } 106 Flush(); 107 } 108 109 /* 110 * requested() gets called for these reasons: 111 * flag == JOBSIG: report nothing; change state to JOBSTOP 112 * flag == JOBSTOP: report "Continued ..." 113 * default: report sleeping system call 114 * 115 * It returns a new flag: JOBSTOP or SLEEPING or 0. 116 */ 117 int 118 requested(private_t *pri, int flag, int dotrace) 119 { 120 const lwpstatus_t *Lsp = pri->lwpstat; 121 int sig = Lsp->pr_cursig; 122 int newflag = 0; 123 124 switch (flag) { 125 case JOBSIG: 126 return (JOBSTOP); 127 128 case JOBSTOP: 129 if (dotrace && !cflag && prismember(&signals, sig)) { 130 pri->length = 0; 131 putpname(pri); 132 timestamp(pri); 133 (void) printf(" Continued with signal #%d, %s", 134 sig, signame(pri, sig)); 135 if (Lsp->pr_action.sa_handler == SIG_DFL) 136 (void) printf(" [default]"); 137 else if (Lsp->pr_action.sa_handler == SIG_IGN) 138 (void) printf(" [ignored]"); 139 else 140 (void) printf(" [caught]"); 141 (void) fputc('\n', stdout); 142 Flush(); 143 } 144 newflag = 0; 145 break; 146 147 default: 148 newflag = SLEEPING; 149 if (!cflag) 150 report_sleeping(pri, dotrace); 151 break; 152 } 153 154 return (newflag); 155 } 156 157 int 158 jobcontrol(private_t *pri, int dotrace) 159 { 160 const lwpstatus_t *Lsp = pri->lwpstat; 161 int sig = stopsig(pri); 162 163 if (sig == 0) 164 return (0); 165 166 if (dotrace && !cflag && /* not just counting */ 167 prismember(&signals, sig)) { /* tracing this signal */ 168 int sys; 169 170 pri->length = 0; 171 putpname(pri); 172 timestamp(pri); 173 (void) printf(" Stopped by signal #%d, %s", 174 sig, signame(pri, sig)); 175 if ((Lsp->pr_flags & PR_ASLEEP) && 176 (sys = Lsp->pr_syscall) > 0 && sys <= PRMAXSYS) 177 (void) printf(", in %s()", 178 sysname(pri, sys, getsubcode(pri))); 179 (void) fputc('\n', stdout); 180 Flush(); 181 } 182 183 return (JOBSTOP); 184 } 185 186 /* 187 * Return the signal the process stopped on iff process is already stopped on 188 * PR_JOBCONTROL or is stopped on PR_SIGNALLED or PR_REQUESTED with a current 189 * signal that will cause a JOBCONTROL stop when the process is set running. 190 */ 191 int 192 stopsig(private_t *pri) 193 { 194 const lwpstatus_t *Lsp = pri->lwpstat; 195 int sig = 0; 196 197 if (Lsp->pr_flags & PR_STOPPED) { 198 switch (Lsp->pr_why) { 199 case PR_JOBCONTROL: 200 sig = Lsp->pr_what; 201 if (sig < 0 || sig > PRMAXSIG) 202 sig = 0; 203 break; 204 case PR_SIGNALLED: 205 case PR_REQUESTED: 206 if (Lsp->pr_action.sa_handler == SIG_DFL) { 207 switch (Lsp->pr_cursig) { 208 case SIGSTOP: 209 sig = SIGSTOP; 210 break; 211 case SIGTSTP: 212 case SIGTTIN: 213 case SIGTTOU: 214 if (!(Lsp->pr_flags & PR_ORPHAN)) 215 sig = Lsp->pr_cursig; 216 break; 217 } 218 } 219 break; 220 } 221 } 222 223 return (sig); 224 } 225 226 int 227 signalled(private_t *pri, int flag, int dotrace) 228 { 229 const lwpstatus_t *Lsp = pri->lwpstat; 230 int sig = Lsp->pr_what; 231 232 if (sig <= 0 || sig > PRMAXSIG) /* check bounds */ 233 return (0); 234 235 if (dotrace && cflag) { /* just counting */ 236 (void) mutex_lock(&count_lock); 237 Cp->sigcount[sig]++; 238 (void) mutex_unlock(&count_lock); 239 } 240 241 if (sig == SIGCONT && (flag == JOBSIG || flag == JOBSTOP)) 242 flag = requested(pri, JOBSTOP, dotrace); 243 else if ((flag = jobcontrol(pri, dotrace)) == 0 && 244 !cflag && dotrace && 245 prismember(&signals, sig)) { 246 int sys; 247 248 pri->length = 0; 249 putpname(pri); 250 timestamp(pri); 251 (void) printf(" Received signal #%d, %s", 252 sig, signame(pri, sig)); 253 if ((Lsp->pr_flags & PR_ASLEEP) && 254 (sys = Lsp->pr_syscall) > 0 && sys <= PRMAXSYS) 255 (void) printf(", in %s()", 256 sysname(pri, sys, getsubcode(pri))); 257 if (Lsp->pr_action.sa_handler == SIG_DFL) 258 (void) printf(" [default]"); 259 else if (Lsp->pr_action.sa_handler == SIG_IGN) 260 (void) printf(" [ignored]"); 261 else 262 (void) printf(" [caught]"); 263 (void) fputc('\n', stdout); 264 if (Lsp->pr_info.si_code != 0 || 265 Lsp->pr_info.si_pid != 0) 266 print_siginfo(pri, &Lsp->pr_info); 267 Flush(); 268 } 269 270 if (flag == JOBSTOP) 271 flag = JOBSIG; 272 return (flag); 273 } 274 275 int 276 faulted(private_t *pri, int dotrace) 277 { 278 const lwpstatus_t *Lsp = pri->lwpstat; 279 int flt = Lsp->pr_what; 280 281 if ((uint_t)flt > PRMAXFAULT || !prismember(&faults, flt) || !dotrace) 282 return (0); 283 284 (void) mutex_lock(&count_lock); 285 Cp->fltcount[flt]++; 286 (void) mutex_unlock(&count_lock); 287 288 if (cflag) /* just counting */ 289 return (1); 290 291 pri->length = 0; 292 putpname(pri); 293 timestamp(pri); 294 295 (void) printf(" Incurred fault #%d, %s %%pc = 0x%.8lX", 296 flt, proc_fltname(flt, pri->flt_name, sizeof (pri->flt_name)), 297 (long)Lsp->pr_reg[R_PC]); 298 299 if (flt == FLTPAGE) 300 (void) printf(" addr = 0x%.8lX", 301 (long)Lsp->pr_info.si_addr); 302 (void) fputc('\n', stdout); 303 if (Lsp->pr_info.si_signo != 0) 304 print_siginfo(pri, &Lsp->pr_info); 305 Flush(); 306 return (1); 307 } 308 309 /* 310 * Set up pri->sys_nargs and pri->sys_args[] (syscall args). 311 */ 312 void 313 setupsysargs(private_t *pri, int what) 314 { 315 const lwpstatus_t *Lsp = pri->lwpstat; 316 int nargs; 317 int i; 318 319 #if sparc 320 /* determine whether syscall is indirect */ 321 pri->sys_indirect = (Lsp->pr_reg[R_G1] == SYS_syscall)? 1 : 0; 322 #else 323 pri->sys_indirect = 0; 324 #endif 325 326 (void) memset(pri->sys_args, 0, sizeof (pri->sys_args)); 327 if (what != Lsp->pr_syscall) { /* assertion */ 328 (void) printf("%s\t*** Inconsistent syscall: %d vs %d ***\n", 329 pri->pname, what, Lsp->pr_syscall); 330 } 331 nargs = Lsp->pr_nsysarg; 332 for (i = 0; 333 i < nargs && i < sizeof (pri->sys_args) / sizeof (pri->sys_args[0]); 334 i++) 335 pri->sys_args[i] = Lsp->pr_sysarg[i]; 336 pri->sys_nargs = nargs; 337 } 338 339 #define ISREAD(code) \ 340 ((code) == SYS_read || (code) == SYS_pread || \ 341 (code) == SYS_pread64 || (code) == SYS_readv || \ 342 (code) == SYS_recv || (code) == SYS_recvfrom) 343 #define ISWRITE(code) \ 344 ((code) == SYS_write || (code) == SYS_pwrite || \ 345 (code) == SYS_pwrite64 || (code) == SYS_writev || \ 346 (code) == SYS_send || (code) == SYS_sendto) 347 348 /* 349 * Return TRUE iff syscall is being traced. 350 */ 351 int 352 sysentry(private_t *pri, int dotrace) 353 { 354 pid_t pid = Pstatus(Proc)->pr_pid; 355 const lwpstatus_t *Lsp = pri->lwpstat; 356 long arg; 357 int nargs; 358 int i; 359 int x; 360 int len; 361 char *s; 362 const struct systable *stp; 363 int what = Lsp->pr_what; 364 int subcode; 365 int istraced; 366 int raw; 367 368 /* for reporting sleeping system calls */ 369 if (what == 0 && (Lsp->pr_flags & (PR_ASLEEP|PR_VFORKP))) 370 what = Lsp->pr_syscall; 371 372 /* protect ourself from operating system error */ 373 if (what <= 0 || what > PRMAXSYS) 374 what = 0; 375 376 /* 377 * Set up the system call arguments (pri->sys_nargs & pri->sys_args[]). 378 */ 379 setupsysargs(pri, what); 380 nargs = pri->sys_nargs; 381 382 /* get systable entry for this syscall */ 383 subcode = getsubcode(pri); 384 stp = subsys(what, subcode); 385 386 if (nargs > stp->nargs) 387 nargs = stp->nargs; 388 pri->sys_nargs = nargs; 389 390 /* 391 * Fetch and remember first argument if it's a string, 392 * or second argument if SYS_openat or SYS_openat64. 393 */ 394 pri->sys_valid = FALSE; 395 if ((nargs > 0 && stp->arg[0] == STG) || 396 (nargs > 1 && (what == SYS_openat || what == SYS_openat64))) { 397 long offset; 398 uint32_t offset32; 399 400 /* 401 * Special case for exit from exec(). 402 * The address in pri->sys_args[0] refers to the old process 403 * image. We must fetch the string from the new image. 404 */ 405 if (Lsp->pr_why == PR_SYSEXIT && what == SYS_execve) { 406 psinfo_t psinfo; 407 long argv; 408 auxv_t auxv[32]; 409 int naux; 410 411 offset = 0; 412 naux = proc_get_auxv(pid, auxv, 32); 413 for (i = 0; i < naux; i++) { 414 if (auxv[i].a_type == AT_SUN_EXECNAME) { 415 offset = (long)auxv[i].a_un.a_ptr; 416 break; 417 } 418 } 419 if (offset == 0 && 420 proc_get_psinfo(pid, &psinfo) == 0) { 421 argv = (long)psinfo.pr_argv; 422 if (data_model == PR_MODEL_LP64) 423 (void) Pread(Proc, &offset, 424 sizeof (offset), argv); 425 else { 426 offset32 = 0; 427 (void) Pread(Proc, &offset32, 428 sizeof (offset32), argv); 429 offset = offset32; 430 } 431 } 432 } else if (stp->arg[0] == STG) { 433 offset = pri->sys_args[0]; 434 } else { 435 offset = pri->sys_args[1]; 436 } 437 if ((s = fetchstring(pri, offset, PATH_MAX)) != NULL) { 438 pri->sys_valid = TRUE; 439 len = strlen(s); 440 /* reallocate if necessary */ 441 while (len >= pri->sys_psize) { 442 free(pri->sys_path); 443 pri->sys_path = my_malloc(pri->sys_psize *= 2, 444 "pathname buffer"); 445 } 446 (void) strcpy(pri->sys_path, s); /* remember pathname */ 447 } 448 } 449 450 istraced = dotrace && prismember(&trace, what); 451 raw = prismember(&rawout, what); 452 453 /* force tracing of read/write buffer dump syscalls */ 454 if (!istraced && nargs > 2) { 455 int fdp1 = (int)pri->sys_args[0] + 1; 456 457 if (ISREAD(what)) { 458 if (prismember(&readfd, fdp1)) 459 istraced = TRUE; 460 } else if (ISWRITE(what)) { 461 if (prismember(&writefd, fdp1)) 462 istraced = TRUE; 463 } 464 } 465 466 pri->sys_leng = 0; 467 if (cflag || !istraced) /* just counting */ 468 *pri->sys_string = 0; 469 else { 470 int argprinted = FALSE; 471 const char *name; 472 473 name = sysname(pri, what, raw? -1 : subcode); 474 grow(pri, strlen(name) + 1); 475 pri->sys_leng = snprintf(pri->sys_string, pri->sys_ssize, 476 "%s(", name); 477 for (i = 0; i < nargs; i++) { 478 arg = pri->sys_args[i]; 479 x = stp->arg[i]; 480 481 if (!raw && pri->sys_valid && 482 ((i == 0 && x == STG) || 483 (i == 1 && (what == SYS_openat || 484 what == SYS_openat64)))) { /* already fetched */ 485 if (argprinted) 486 outstring(pri, ", "); 487 escape_string(pri, pri->sys_path); 488 argprinted = TRUE; 489 } else if (x != NOV && (x != HID || raw)) { 490 if (argprinted) 491 outstring(pri, ", "); 492 if (x == LLO) 493 (*Print[x])(pri, raw, arg, 494 pri->sys_args[++i]); 495 else 496 (*Print[x])(pri, raw, arg); 497 argprinted = TRUE; 498 } 499 } 500 outstring(pri, ")"); 501 } 502 503 return (istraced); 504 } 505 #undef ISREAD 506 #undef ISWRITE 507 508 /* 509 * sysexit() returns non-zero if anything was printed. 510 */ 511 int 512 sysexit(private_t *pri, int dotrace) 513 { 514 const lwpstatus_t *Lsp = pri->lwpstat; 515 int what = Lsp->pr_what; 516 struct syscount *scp; 517 const struct systable *stp; 518 int subcode; 519 int istraced; 520 int raw; 521 522 /* protect ourself from operating system error */ 523 if (what <= 0 || what > PRMAXSYS) 524 return (0); 525 526 /* 527 * If we aren't supposed to be tracing this one, then 528 * delete it from the traced signal set. We got here 529 * because the process was sleeping in an untraced syscall. 530 */ 531 if (!prismember(&traceeven, what)) { 532 (void) Psysexit(Proc, what, FALSE); 533 return (0); 534 } 535 536 /* pick up registers & set pri->Errno before anything else */ 537 pri->Errno = Lsp->pr_errno; 538 pri->ErrPriv = Lsp->pr_errpriv; 539 pri->Rval1 = Lsp->pr_rval1; 540 pri->Rval2 = Lsp->pr_rval2; 541 542 switch (what) { 543 case SYS_exit: /* these are traced on entry */ 544 case SYS_lwp_exit: 545 case SYS_context: 546 istraced = dotrace && prismember(&trace, what); 547 break; 548 case SYS_execve: /* this is normally traced on entry */ 549 istraced = dotrace && prismember(&trace, what); 550 if (pri->exec_string && *pri->exec_string) { 551 if (!cflag && istraced) { /* print exec() string now */ 552 if (pri->exec_pname[0] != '\0') 553 (void) fputs(pri->exec_pname, stdout); 554 timestamp(pri); 555 (void) fputs(pri->exec_string, stdout); 556 } 557 pri->exec_pname[0] = '\0'; 558 pri->exec_string[0] = '\0'; 559 break; 560 } 561 /* FALLTHROUGH */ 562 default: 563 /* we called sysentry() in main() for these */ 564 if (what == SYS_openat || what == SYS_openat64 || 565 what == SYS_open || what == SYS_open64) 566 istraced = dotrace && prismember(&trace, what); 567 else 568 istraced = sysentry(pri, dotrace) && dotrace; 569 pri->length = 0; 570 if (!cflag && istraced) { 571 putpname(pri); 572 timestamp(pri); 573 pri->length += printf("%s", pri->sys_string); 574 } 575 pri->sys_leng = 0; 576 *pri->sys_string = '\0'; 577 break; 578 } 579 580 /* get systable entry for this syscall */ 581 subcode = getsubcode(pri); 582 stp = subsys(what, subcode); 583 584 if (cflag && istraced) { 585 (void) mutex_lock(&count_lock); 586 scp = Cp->syscount[what]; 587 if (what == SYS_forksys && subcode >= 3) 588 scp += subcode - 3; 589 else if (subcode != -1 && 590 (what != SYS_openat && what != SYS_openat64 && 591 what != SYS_open && what != SYS_open64 && 592 what != SYS_lwp_create)) 593 scp += subcode; 594 scp->count++; 595 accumulate(&scp->stime, &Lsp->pr_stime, &pri->syslast); 596 accumulate(&Cp->usrtotal, &Lsp->pr_utime, &pri->usrlast); 597 pri->syslast = Lsp->pr_stime; 598 pri->usrlast = Lsp->pr_utime; 599 (void) mutex_unlock(&count_lock); 600 } 601 602 raw = prismember(&rawout, what); 603 604 if (!cflag && istraced) { 605 if ((what == SYS_vfork || what == SYS_forksys) && 606 pri->Errno == 0 && pri->Rval2 != 0) { 607 pri->length &= ~07; 608 if (strlen(sysname(pri, what, raw? -1 : subcode)) < 6) { 609 (void) fputc('\t', stdout); 610 pri->length += 8; 611 } 612 pri->length += 613 7 + printf("\t(returning as child ...)"); 614 } 615 if (what == SYS_lwp_create && 616 pri->Errno == 0 && pri->Rval1 == 0) { 617 pri->length &= ~07; 618 pri->length += 619 7 + printf("\t(returning as new lwp ...)"); 620 } 621 if (pri->Errno != 0 || what != SYS_execve) { 622 /* prepare to print the return code */ 623 pri->length >>= 3; 624 if (pri->length >= 6) 625 (void) fputc(' ', stdout); 626 for (; pri->length < 6; pri->length++) 627 (void) fputc('\t', stdout); 628 } 629 } 630 pri->length = 0; 631 632 if (pri->Errno != 0) { /* error in syscall */ 633 if (istraced) { 634 if (cflag) 635 scp->error++; 636 else { 637 const char *ename = errname(pri->Errno); 638 const char *privname; 639 640 (void) printf("Err#%d", pri->Errno); 641 if (ename != NULL) { 642 (void) fputc(' ', stdout); 643 (void) fputs(ename, stdout); 644 } 645 switch (pri->ErrPriv) { 646 case PRIV_NONE: 647 privname = NULL; 648 break; 649 case PRIV_ALL: 650 privname = "ALL"; 651 break; 652 case PRIV_MULTIPLE: 653 privname = "MULTIPLE"; 654 break; 655 case PRIV_ALLZONE: 656 privname = "ZONE"; 657 break; 658 default: 659 privname = priv_getbynum(pri->ErrPriv); 660 break; 661 } 662 if (privname != NULL) 663 (void) printf(" [%s]", privname); 664 665 (void) fputc('\n', stdout); 666 } 667 } 668 } else { 669 /* show arguments on successful exec */ 670 if (what == SYS_execve) { 671 if (!cflag && istraced) 672 showargs(pri, raw); 673 } else if (!cflag && istraced) { 674 const char *fmt = NULL; 675 long rv1 = pri->Rval1; 676 long rv2 = pri->Rval2; 677 678 #ifdef _LP64 679 /* 680 * 32-bit system calls return 32-bit values. We 681 * later mask out the upper bits if we want to 682 * print these as unsigned values. 683 */ 684 if (data_model == PR_MODEL_ILP32) { 685 rv1 = (int)rv1; 686 rv2 = (int)rv2; 687 } 688 #endif 689 690 switch (what) { 691 case SYS_llseek: 692 rv1 &= 0xffffffff; 693 rv2 &= 0xffffffff; 694 #ifdef _LONG_LONG_LTOH /* first long of a longlong is the low order */ 695 if (rv2 != 0) { 696 long temp = rv1; 697 fmt = "= 0x%lX%.8lX"; 698 rv1 = rv2; 699 rv2 = temp; 700 break; 701 } 702 #else /* the other way around */ 703 if (rv1 != 0) { 704 fmt = "= 0x%lX%.8lX"; 705 break; 706 } 707 rv1 = rv2; /* ugly */ 708 #endif 709 /* FALLTHROUGH */ 710 case SYS_lseek: 711 case SYS_ulimit: 712 if (rv1 & 0xff000000) { 713 #ifdef _LP64 714 if (data_model == PR_MODEL_ILP32) 715 rv1 &= 0xffffffff; 716 #endif 717 fmt = "= 0x%.8lX"; 718 } 719 break; 720 case SYS_sigtimedwait: 721 if (raw) 722 /* EMPTY */; 723 else if ((fmt = rawsigname(pri, rv1)) != NULL) { 724 rv1 = (long)fmt; /* filthy */ 725 fmt = "= %s"; 726 } 727 break; 728 case SYS_port: 729 #ifdef _LP64 730 if (data_model == PR_MODEL_LP64) { 731 rv2 = rv1 & 0xffffffff; 732 rv1 = rv1 >> 32; 733 } 734 #endif 735 break; 736 } 737 738 if (fmt == NULL) { 739 switch (stp->rval[0]) { 740 case HEX: 741 #ifdef _LP64 742 if (data_model == PR_MODEL_ILP32) 743 rv1 &= 0xffffffff; 744 #endif 745 fmt = "= 0x%.8lX"; 746 break; 747 case HHX: 748 #ifdef _LP64 749 if (data_model == PR_MODEL_ILP32) 750 rv1 &= 0xffffffff; 751 #endif 752 fmt = "= 0x%.4lX"; 753 break; 754 case OCT: 755 #ifdef _LP64 756 if (data_model == PR_MODEL_ILP32) 757 rv1 &= 0xffffffff; 758 #endif 759 fmt = "= %#lo"; 760 break; 761 case UNS: 762 #ifdef _LP64 763 if (data_model == PR_MODEL_ILP32) 764 rv1 &= 0xffffffff; 765 #endif 766 fmt = "= %lu"; 767 break; 768 default: 769 fmt = "= %ld"; 770 break; 771 } 772 } 773 774 (void) printf(fmt, rv1, rv2); 775 776 switch (stp->rval[1]) { 777 case NOV: 778 fmt = NULL; 779 break; 780 case HEX: 781 #ifdef _LP64 782 if (data_model == PR_MODEL_ILP32) 783 rv2 &= 0xffffffff; 784 #endif 785 fmt = " [0x%.8lX]"; 786 break; 787 case HHX: 788 #ifdef _LP64 789 if (data_model == PR_MODEL_ILP32) 790 rv2 &= 0xffffffff; 791 #endif 792 fmt = " [0x%.4lX]"; 793 break; 794 case OCT: 795 #ifdef _LP64 796 if (data_model == PR_MODEL_ILP32) 797 rv2 &= 0xffffffff; 798 #endif 799 fmt = " [%#lo]"; 800 break; 801 case UNS: 802 #ifdef _LP64 803 if (data_model == PR_MODEL_ILP32) 804 rv2 &= 0xffffffff; 805 #endif 806 fmt = " [%lu]"; 807 break; 808 default: 809 fmt = " [%ld]"; 810 break; 811 } 812 813 if (fmt != NULL) 814 (void) printf(fmt, rv2); 815 (void) fputc('\n', stdout); 816 } 817 818 if (what == SYS_vfork || what == SYS_forksys) { 819 if (pri->Rval2 == 0) /* child was created */ 820 pri->child = pri->Rval1; 821 else if (cflag && istraced) /* this is the child */ 822 scp->count--; 823 } 824 if (what == SYS_lwp_create && pri->Rval1 == 0 && 825 cflag && istraced) /* this is the created lwp */ 826 scp->count--; 827 } 828 829 #define ISREAD(code) \ 830 ((code) == SYS_read || (code) == SYS_pread || (code) == SYS_pread64 || \ 831 (code) == SYS_recv || (code) == SYS_recvfrom) 832 #define ISWRITE(code) \ 833 ((code) == SYS_write || (code) == SYS_pwrite || \ 834 (code) == SYS_pwrite64 || (code) == SYS_send || (code) == SYS_sendto) 835 836 if (!cflag && istraced) { 837 int fdp1 = (int)pri->sys_args[0] + 1; /* filedescriptor + 1 */ 838 839 if (raw) { 840 if (what != SYS_execve) 841 showpaths(pri, stp); 842 if (ISREAD(what) || ISWRITE(what)) { 843 if (pri->iob_buf[0] != '\0') 844 (void) printf("%s 0x%.8lX: %s\n", 845 pri->pname, pri->sys_args[1], 846 pri->iob_buf); 847 } 848 } 849 850 /* 851 * Show buffer contents for read()/pread() or write()/pwrite(). 852 * IOBSIZE bytes have already been shown; 853 * don't show them again unless there's more. 854 */ 855 if ((ISREAD(what) && pri->Errno == 0 && 856 prismember(&readfd, fdp1)) || 857 (ISWRITE(what) && prismember(&writefd, fdp1))) { 858 long nb = ISWRITE(what) ? pri->sys_args[2] : pri->Rval1; 859 860 if (nb > IOBSIZE) { 861 /* enter region of lengthy output */ 862 if (nb > MYBUFSIZ / 4) 863 Eserialize(); 864 865 showbuffer(pri, pri->sys_args[1], nb); 866 867 /* exit region of lengthy output */ 868 if (nb > MYBUFSIZ / 4) 869 Xserialize(); 870 } 871 } 872 #undef ISREAD 873 #undef ISWRITE 874 /* 875 * Do verbose interpretation if requested. 876 * If buffer contents for read or write have been requested and 877 * this is a readv() or writev(), force verbose interpretation. 878 */ 879 if (prismember(&verbose, what) || 880 ((what == SYS_readv || what == SYS_recvmsg) && 881 pri->Errno == 0 && prismember(&readfd, fdp1)) || 882 ((what == SYS_writev || what == SYS_sendfilev || 883 what == SYS_sendmsg) && 884 prismember(&writefd, fdp1))) 885 expound(pri, pri->Rval1, raw); 886 } 887 888 return (!cflag && istraced); 889 } 890 891 void 892 showpaths(private_t *pri, const struct systable *stp) 893 { 894 int what = pri->lwpstat->pr_what; 895 int i; 896 897 for (i = 0; i < pri->sys_nargs; i++) { 898 if (stp->arg[i] == ATC && (int)pri->sys_args[i] == AT_FDCWD) { 899 (void) printf("%s 0x%.8X: AT_FDCWD\n", 900 pri->pname, AT_FDCWD); 901 } else if ((stp->arg[i] == STG) || 902 (stp->arg[i] == RST && !pri->Errno) || 903 (stp->arg[i] == RLK && !pri->Errno && pri->Rval1 > 0)) { 904 long addr = pri->sys_args[i]; 905 int maxleng = 906 (stp->arg[i] == RLK)? (int)pri->Rval1 : PATH_MAX; 907 char *s; 908 909 if (pri->sys_valid && 910 ((i == 0 && stp->arg[0] == STG) || 911 (i == 1 && (what == SYS_openat || 912 what == SYS_openat64)))) /* already fetched */ 913 s = pri->sys_path; 914 else 915 s = fetchstring(pri, addr, 916 maxleng > PATH_MAX ? PATH_MAX : maxleng); 917 918 if (s != (char *)NULL) 919 (void) printf("%s 0x%.8lX: \"%s\"\n", 920 pri->pname, addr, s); 921 } 922 } 923 } 924 925 /* 926 * Display arguments to successful exec(). 927 */ 928 void 929 showargs(private_t *pri, int raw) 930 { 931 const lwpstatus_t *Lsp = pri->lwpstat; 932 int nargs; 933 long ap; 934 int ptrsize; 935 int fail; 936 937 pri->length = 0; 938 ptrsize = (data_model == PR_MODEL_LP64)? 8 : 4; 939 940 #if defined(__i386) || defined(__amd64) /* XX64 */ 941 ap = (long)Lsp->pr_reg[R_SP]; 942 fail = (Pread(Proc, &nargs, sizeof (nargs), ap) != sizeof (nargs)); 943 ap += ptrsize; 944 #endif /* i386 */ 945 946 #if sparc 947 if (data_model == PR_MODEL_LP64) { 948 int64_t xnargs; 949 ap = (long)(Lsp->pr_reg[R_SP]) + 16 * sizeof (int64_t) 950 + STACK_BIAS; 951 fail = (Pread(Proc, &xnargs, sizeof (xnargs), ap) != 952 sizeof (xnargs)); 953 nargs = (int)xnargs; 954 } else { 955 ap = (long)(Lsp->pr_reg[R_SP]) + 16 * sizeof (int32_t); 956 fail = (Pread(Proc, &nargs, sizeof (nargs), ap) != 957 sizeof (nargs)); 958 } 959 ap += ptrsize; 960 #endif /* sparc */ 961 962 if (fail) { 963 (void) printf("\n%s\t*** Bad argument list? ***\n", pri->pname); 964 return; 965 } 966 967 (void) printf(" argc = %d\n", nargs); 968 if (raw) 969 showpaths(pri, &systable[SYS_execve]); 970 971 show_cred(pri, FALSE, FALSE); 972 973 if (aflag || eflag) { /* dump args or environment */ 974 975 /* enter region of (potentially) lengthy output */ 976 Eserialize(); 977 978 if (aflag) /* dump the argument list */ 979 dumpargs(pri, ap, "argv:"); 980 ap += (nargs+1) * ptrsize; 981 if (eflag) /* dump the environment */ 982 dumpargs(pri, ap, "envp:"); 983 984 /* exit region of lengthy output */ 985 Xserialize(); 986 } 987 } 988 989 void 990 dumpargs(private_t *pri, long ap, const char *str) 991 { 992 char *string; 993 unsigned int leng = 0; 994 int ptrsize; 995 long arg = 0; 996 char *argaddr; 997 char badaddr[32]; 998 999 if (interrupt) 1000 return; 1001 1002 #ifdef _LP64 1003 if (data_model == PR_MODEL_LP64) { 1004 argaddr = (char *)&arg; 1005 ptrsize = 8; 1006 } else { 1007 #if defined(_LITTLE_ENDIAN) 1008 argaddr = (char *)&arg; 1009 #else 1010 argaddr = (char *)&arg + 4; 1011 #endif 1012 ptrsize = 4; 1013 } 1014 #else 1015 argaddr = (char *)&arg; 1016 ptrsize = 4; 1017 #endif 1018 putpname(pri); 1019 (void) fputc(' ', stdout); 1020 (void) fputs(str, stdout); 1021 leng += 1 + strlen(str); 1022 1023 while (!interrupt) { 1024 if (Pread(Proc, argaddr, ptrsize, ap) != ptrsize) { 1025 (void) printf("\n%s\t*** Bad argument list? ***\n", 1026 pri->pname); 1027 return; 1028 } 1029 ap += ptrsize; 1030 1031 if (arg == 0) 1032 break; 1033 string = fetchstring(pri, arg, PATH_MAX); 1034 if (string == NULL) { 1035 (void) sprintf(badaddr, "BadAddress:0x%.8lX", arg); 1036 string = badaddr; 1037 } 1038 if ((leng += strlen(string)) < 63) { 1039 (void) fputc(' ', stdout); 1040 leng++; 1041 } else { 1042 (void) fputc('\n', stdout); 1043 leng = 0; 1044 putpname(pri); 1045 (void) fputs(" ", stdout); 1046 leng += 2 + strlen(string); 1047 } 1048 (void) fputs(string, stdout); 1049 } 1050 (void) fputc('\n', stdout); 1051 } 1052 1053 /* 1054 * Display contents of read() or write() buffer. 1055 */ 1056 void 1057 showbuffer(private_t *pri, long offset, long count) 1058 { 1059 char buffer[320]; 1060 int nbytes; 1061 char *buf; 1062 int n; 1063 1064 while (count > 0 && !interrupt) { 1065 nbytes = (count < sizeof (buffer))? count : sizeof (buffer); 1066 if ((nbytes = Pread(Proc, buffer, nbytes, offset)) <= 0) 1067 break; 1068 count -= nbytes; 1069 offset += nbytes; 1070 buf = buffer; 1071 while (nbytes > 0 && !interrupt) { 1072 char obuf[65]; 1073 1074 n = (nbytes < 32)? nbytes : 32; 1075 showbytes(buf, n, obuf); 1076 1077 putpname(pri); 1078 (void) fputs(" ", stdout); 1079 (void) fputs(obuf, stdout); 1080 (void) fputc('\n', stdout); 1081 nbytes -= n; 1082 buf += n; 1083 } 1084 } 1085 } 1086 1087 void 1088 showbytes(const char *buf, int n, char *obuf) 1089 { 1090 int c; 1091 1092 while (--n >= 0) { 1093 int c1 = '\\'; 1094 int c2; 1095 1096 switch (c = (*buf++ & 0xff)) { 1097 case '\0': 1098 c2 = '0'; 1099 break; 1100 case '\b': 1101 c2 = 'b'; 1102 break; 1103 case '\t': 1104 c2 = 't'; 1105 break; 1106 case '\n': 1107 c2 = 'n'; 1108 break; 1109 case '\v': 1110 c2 = 'v'; 1111 break; 1112 case '\f': 1113 c2 = 'f'; 1114 break; 1115 case '\r': 1116 c2 = 'r'; 1117 break; 1118 default: 1119 if (isprint(c)) { 1120 c1 = ' '; 1121 c2 = c; 1122 } else { 1123 c1 = c>>4; 1124 c1 += (c1 < 10)? '0' : 'A'-10; 1125 c2 = c&0xf; 1126 c2 += (c2 < 10)? '0' : 'A'-10; 1127 } 1128 break; 1129 } 1130 *obuf++ = (char)c1; 1131 *obuf++ = (char)c2; 1132 } 1133 1134 *obuf = '\0'; 1135 }