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 escape_string(pri, pri->sys_path); 486 argprinted = TRUE; 487 } else if (x != HID || raw) { 488 if (argprinted) 489 outstring(pri, ", "); 490 if (x == LLO) 491 (*Print[x])(pri, raw, arg, 492 pri->sys_args[++i]); 493 else 494 (*Print[x])(pri, raw, arg); 495 /* 496 * if nothing printed, then don't print ", " 497 */ 498 if (x == NOV) 499 argprinted = FALSE; 500 else 501 argprinted = TRUE; 502 } 503 } 504 outstring(pri, ")"); 505 } 506 507 return (istraced); 508 } 509 #undef ISREAD 510 #undef ISWRITE 511 512 /* 513 * sysexit() returns non-zero if anything was printed. 514 */ 515 int 516 sysexit(private_t *pri, int dotrace) 517 { 518 const lwpstatus_t *Lsp = pri->lwpstat; 519 int what = Lsp->pr_what; 520 struct syscount *scp; 521 const struct systable *stp; 522 int subcode; 523 int istraced; 524 int raw; 525 526 /* protect ourself from operating system error */ 527 if (what <= 0 || what > PRMAXSYS) 528 return (0); 529 530 /* 531 * If we aren't supposed to be tracing this one, then 532 * delete it from the traced signal set. We got here 533 * because the process was sleeping in an untraced syscall. 534 */ 535 if (!prismember(&traceeven, what)) { 536 (void) Psysexit(Proc, what, FALSE); 537 return (0); 538 } 539 540 /* pick up registers & set pri->Errno before anything else */ 541 pri->Errno = Lsp->pr_errno; 542 pri->ErrPriv = Lsp->pr_errpriv; 543 pri->Rval1 = Lsp->pr_rval1; 544 pri->Rval2 = Lsp->pr_rval2; 545 546 switch (what) { 547 case SYS_exit: /* these are traced on entry */ 548 case SYS_lwp_exit: 549 case SYS_context: 550 istraced = dotrace && prismember(&trace, what); 551 break; 552 case SYS_execve: /* this is normally traced on entry */ 553 istraced = dotrace && prismember(&trace, what); 554 if (pri->exec_string && *pri->exec_string) { 555 if (!cflag && istraced) { /* print exec() string now */ 556 if (pri->exec_pname[0] != '\0') 557 (void) fputs(pri->exec_pname, stdout); 558 timestamp(pri); 559 (void) fputs(pri->exec_string, stdout); 560 } 561 pri->exec_pname[0] = '\0'; 562 pri->exec_string[0] = '\0'; 563 break; 564 } 565 /* FALLTHROUGH */ 566 default: 567 /* we called sysentry() in main() for these */ 568 if (what == SYS_openat || what == SYS_openat64 || 569 what == SYS_open || what == SYS_open64) 570 istraced = dotrace && prismember(&trace, what); 571 else 572 istraced = sysentry(pri, dotrace) && dotrace; 573 pri->length = 0; 574 if (!cflag && istraced) { 575 putpname(pri); 576 timestamp(pri); 577 pri->length += printf("%s", pri->sys_string); 578 } 579 pri->sys_leng = 0; 580 *pri->sys_string = '\0'; 581 break; 582 } 583 584 /* get systable entry for this syscall */ 585 subcode = getsubcode(pri); 586 stp = subsys(what, subcode); 587 588 if (cflag && istraced) { 589 (void) mutex_lock(&count_lock); 590 scp = Cp->syscount[what]; 591 if (what == SYS_forksys && subcode >= 3) 592 scp += subcode - 3; 593 else if (subcode != -1 && 594 (what != SYS_openat && what != SYS_openat64 && 595 what != SYS_open && what != SYS_open64 && 596 what != SYS_lwp_create)) 597 scp += subcode; 598 scp->count++; 599 accumulate(&scp->stime, &Lsp->pr_stime, &pri->syslast); 600 accumulate(&Cp->usrtotal, &Lsp->pr_utime, &pri->usrlast); 601 pri->syslast = Lsp->pr_stime; 602 pri->usrlast = Lsp->pr_utime; 603 (void) mutex_unlock(&count_lock); 604 } 605 606 raw = prismember(&rawout, what); 607 608 if (!cflag && istraced) { 609 if ((what == SYS_vfork || what == SYS_forksys) && 610 pri->Errno == 0 && pri->Rval2 != 0) { 611 pri->length &= ~07; 612 if (strlen(sysname(pri, what, raw? -1 : subcode)) < 6) { 613 (void) fputc('\t', stdout); 614 pri->length += 8; 615 } 616 pri->length += 617 7 + printf("\t(returning as child ...)"); 618 } 619 if (what == SYS_lwp_create && 620 pri->Errno == 0 && pri->Rval1 == 0) { 621 pri->length &= ~07; 622 pri->length += 623 7 + printf("\t(returning as new lwp ...)"); 624 } 625 if (pri->Errno != 0 || what != SYS_execve) { 626 /* prepare to print the return code */ 627 pri->length >>= 3; 628 if (pri->length >= 6) 629 (void) fputc(' ', stdout); 630 for (; pri->length < 6; pri->length++) 631 (void) fputc('\t', stdout); 632 } 633 } 634 pri->length = 0; 635 636 if (pri->Errno != 0) { /* error in syscall */ 637 if (istraced) { 638 if (cflag) 639 scp->error++; 640 else { 641 const char *ename = errname(pri->Errno); 642 const char *privname; 643 644 (void) printf("Err#%d", pri->Errno); 645 if (ename != NULL) { 646 (void) fputc(' ', stdout); 647 (void) fputs(ename, stdout); 648 } 649 switch (pri->ErrPriv) { 650 case PRIV_NONE: 651 privname = NULL; 652 break; 653 case PRIV_ALL: 654 privname = "ALL"; 655 break; 656 case PRIV_MULTIPLE: 657 privname = "MULTIPLE"; 658 break; 659 case PRIV_ALLZONE: 660 privname = "ZONE"; 661 break; 662 default: 663 privname = priv_getbynum(pri->ErrPriv); 664 break; 665 } 666 if (privname != NULL) 667 (void) printf(" [%s]", privname); 668 669 (void) fputc('\n', stdout); 670 } 671 } 672 } else { 673 /* show arguments on successful exec */ 674 if (what == SYS_execve) { 675 if (!cflag && istraced) 676 showargs(pri, raw); 677 } else if (!cflag && istraced) { 678 const char *fmt = NULL; 679 long rv1 = pri->Rval1; 680 long rv2 = pri->Rval2; 681 682 #ifdef _LP64 683 /* 684 * 32-bit system calls return 32-bit values. We 685 * later mask out the upper bits if we want to 686 * print these as unsigned values. 687 */ 688 if (data_model == PR_MODEL_ILP32) { 689 rv1 = (int)rv1; 690 rv2 = (int)rv2; 691 } 692 #endif 693 694 switch (what) { 695 case SYS_llseek: 696 rv1 &= 0xffffffff; 697 rv2 &= 0xffffffff; 698 #ifdef _LONG_LONG_LTOH /* first long of a longlong is the low order */ 699 if (rv2 != 0) { 700 long temp = rv1; 701 fmt = "= 0x%lX%.8lX"; 702 rv1 = rv2; 703 rv2 = temp; 704 break; 705 } 706 #else /* the other way around */ 707 if (rv1 != 0) { 708 fmt = "= 0x%lX%.8lX"; 709 break; 710 } 711 rv1 = rv2; /* ugly */ 712 #endif 713 /* FALLTHROUGH */ 714 case SYS_lseek: 715 case SYS_ulimit: 716 if (rv1 & 0xff000000) { 717 #ifdef _LP64 718 if (data_model == PR_MODEL_ILP32) 719 rv1 &= 0xffffffff; 720 #endif 721 fmt = "= 0x%.8lX"; 722 } 723 break; 724 case SYS_sigtimedwait: 725 if (raw) 726 /* EMPTY */; 727 else if ((fmt = rawsigname(pri, rv1)) != NULL) { 728 rv1 = (long)fmt; /* filthy */ 729 fmt = "= %s"; 730 } 731 break; 732 case SYS_port: 733 #ifdef _LP64 734 if (data_model == PR_MODEL_LP64) { 735 rv2 = rv1 & 0xffffffff; 736 rv1 = rv1 >> 32; 737 } 738 #endif 739 break; 740 } 741 742 if (fmt == NULL) { 743 switch (stp->rval[0]) { 744 case HEX: 745 #ifdef _LP64 746 if (data_model == PR_MODEL_ILP32) 747 rv1 &= 0xffffffff; 748 #endif 749 fmt = "= 0x%.8lX"; 750 break; 751 case HHX: 752 #ifdef _LP64 753 if (data_model == PR_MODEL_ILP32) 754 rv1 &= 0xffffffff; 755 #endif 756 fmt = "= 0x%.4lX"; 757 break; 758 case OCT: 759 #ifdef _LP64 760 if (data_model == PR_MODEL_ILP32) 761 rv1 &= 0xffffffff; 762 #endif 763 fmt = "= %#lo"; 764 break; 765 case UNS: 766 #ifdef _LP64 767 if (data_model == PR_MODEL_ILP32) 768 rv1 &= 0xffffffff; 769 #endif 770 fmt = "= %lu"; 771 break; 772 default: 773 fmt = "= %ld"; 774 break; 775 } 776 } 777 778 (void) printf(fmt, rv1, rv2); 779 780 switch (stp->rval[1]) { 781 case NOV: 782 fmt = NULL; 783 break; 784 case HEX: 785 #ifdef _LP64 786 if (data_model == PR_MODEL_ILP32) 787 rv2 &= 0xffffffff; 788 #endif 789 fmt = " [0x%.8lX]"; 790 break; 791 case HHX: 792 #ifdef _LP64 793 if (data_model == PR_MODEL_ILP32) 794 rv2 &= 0xffffffff; 795 #endif 796 fmt = " [0x%.4lX]"; 797 break; 798 case OCT: 799 #ifdef _LP64 800 if (data_model == PR_MODEL_ILP32) 801 rv2 &= 0xffffffff; 802 #endif 803 fmt = " [%#lo]"; 804 break; 805 case UNS: 806 #ifdef _LP64 807 if (data_model == PR_MODEL_ILP32) 808 rv2 &= 0xffffffff; 809 #endif 810 fmt = " [%lu]"; 811 break; 812 default: 813 fmt = " [%ld]"; 814 break; 815 } 816 817 if (fmt != NULL) 818 (void) printf(fmt, rv2); 819 (void) fputc('\n', stdout); 820 } 821 822 if (what == SYS_vfork || what == SYS_forksys) { 823 if (pri->Rval2 == 0) /* child was created */ 824 pri->child = pri->Rval1; 825 else if (cflag && istraced) /* this is the child */ 826 scp->count--; 827 } 828 if (what == SYS_lwp_create && pri->Rval1 == 0 && 829 cflag && istraced) /* this is the created lwp */ 830 scp->count--; 831 } 832 833 #define ISREAD(code) \ 834 ((code) == SYS_read || (code) == SYS_pread || (code) == SYS_pread64 || \ 835 (code) == SYS_recv || (code) == SYS_recvfrom) 836 #define ISWRITE(code) \ 837 ((code) == SYS_write || (code) == SYS_pwrite || \ 838 (code) == SYS_pwrite64 || (code) == SYS_send || (code) == SYS_sendto) 839 840 if (!cflag && istraced) { 841 int fdp1 = (int)pri->sys_args[0] + 1; /* filedescriptor + 1 */ 842 843 if (raw) { 844 if (what != SYS_execve) 845 showpaths(pri, stp); 846 if (ISREAD(what) || ISWRITE(what)) { 847 if (pri->iob_buf[0] != '\0') 848 (void) printf("%s 0x%.8lX: %s\n", 849 pri->pname, pri->sys_args[1], 850 pri->iob_buf); 851 } 852 } 853 854 /* 855 * Show buffer contents for read()/pread() or write()/pwrite(). 856 * IOBSIZE bytes have already been shown; 857 * don't show them again unless there's more. 858 */ 859 if ((ISREAD(what) && pri->Errno == 0 && 860 prismember(&readfd, fdp1)) || 861 (ISWRITE(what) && prismember(&writefd, fdp1))) { 862 long nb = ISWRITE(what) ? pri->sys_args[2] : pri->Rval1; 863 864 if (nb > IOBSIZE) { 865 /* enter region of lengthy output */ 866 if (nb > MYBUFSIZ / 4) 867 Eserialize(); 868 869 showbuffer(pri, pri->sys_args[1], nb); 870 871 /* exit region of lengthy output */ 872 if (nb > MYBUFSIZ / 4) 873 Xserialize(); 874 } 875 } 876 #undef ISREAD 877 #undef ISWRITE 878 /* 879 * Do verbose interpretation if requested. 880 * If buffer contents for read or write have been requested and 881 * this is a readv() or writev(), force verbose interpretation. 882 */ 883 if (prismember(&verbose, what) || 884 ((what == SYS_readv || what == SYS_recvmsg) && 885 pri->Errno == 0 && prismember(&readfd, fdp1)) || 886 ((what == SYS_writev || what == SYS_sendfilev || 887 what == SYS_sendmsg) && 888 prismember(&writefd, fdp1))) 889 expound(pri, pri->Rval1, raw); 890 } 891 892 return (!cflag && istraced); 893 } 894 895 void 896 showpaths(private_t *pri, const struct systable *stp) 897 { 898 int what = pri->lwpstat->pr_what; 899 int i; 900 901 for (i = 0; i < pri->sys_nargs; i++) { 902 if (stp->arg[i] == ATC && (int)pri->sys_args[i] == AT_FDCWD) { 903 (void) printf("%s 0x%.8X: AT_FDCWD\n", 904 pri->pname, AT_FDCWD); 905 } else if ((stp->arg[i] == STG) || 906 (stp->arg[i] == RST && !pri->Errno) || 907 (stp->arg[i] == RLK && !pri->Errno && pri->Rval1 > 0)) { 908 long addr = pri->sys_args[i]; 909 int maxleng = 910 (stp->arg[i] == RLK)? (int)pri->Rval1 : PATH_MAX; 911 char *s; 912 913 if (pri->sys_valid && 914 ((i == 0 && stp->arg[0] == STG) || 915 (i == 1 && (what == SYS_openat || 916 what == SYS_openat64)))) /* already fetched */ 917 s = pri->sys_path; 918 else 919 s = fetchstring(pri, addr, 920 maxleng > PATH_MAX ? PATH_MAX : maxleng); 921 922 if (s != (char *)NULL) 923 (void) printf("%s 0x%.8lX: \"%s\"\n", 924 pri->pname, addr, s); 925 } 926 } 927 } 928 929 /* 930 * Display arguments to successful exec(). 931 */ 932 void 933 showargs(private_t *pri, int raw) 934 { 935 const lwpstatus_t *Lsp = pri->lwpstat; 936 int nargs; 937 long ap; 938 int ptrsize; 939 int fail; 940 941 pri->length = 0; 942 ptrsize = (data_model == PR_MODEL_LP64)? 8 : 4; 943 944 #if defined(__i386) || defined(__amd64) /* XX64 */ 945 ap = (long)Lsp->pr_reg[R_SP]; 946 fail = (Pread(Proc, &nargs, sizeof (nargs), ap) != sizeof (nargs)); 947 ap += ptrsize; 948 #endif /* i386 */ 949 950 #if sparc 951 if (data_model == PR_MODEL_LP64) { 952 int64_t xnargs; 953 ap = (long)(Lsp->pr_reg[R_SP]) + 16 * sizeof (int64_t) 954 + STACK_BIAS; 955 fail = (Pread(Proc, &xnargs, sizeof (xnargs), ap) != 956 sizeof (xnargs)); 957 nargs = (int)xnargs; 958 } else { 959 ap = (long)(Lsp->pr_reg[R_SP]) + 16 * sizeof (int32_t); 960 fail = (Pread(Proc, &nargs, sizeof (nargs), ap) != 961 sizeof (nargs)); 962 } 963 ap += ptrsize; 964 #endif /* sparc */ 965 966 if (fail) { 967 (void) printf("\n%s\t*** Bad argument list? ***\n", pri->pname); 968 return; 969 } 970 971 (void) printf(" argc = %d\n", nargs); 972 if (raw) 973 showpaths(pri, &systable[SYS_execve]); 974 975 show_cred(pri, FALSE, FALSE); 976 977 if (aflag || eflag) { /* dump args or environment */ 978 979 /* enter region of (potentially) lengthy output */ 980 Eserialize(); 981 982 if (aflag) /* dump the argument list */ 983 dumpargs(pri, ap, "argv:"); 984 ap += (nargs+1) * ptrsize; 985 if (eflag) /* dump the environment */ 986 dumpargs(pri, ap, "envp:"); 987 988 /* exit region of lengthy output */ 989 Xserialize(); 990 } 991 } 992 993 void 994 dumpargs(private_t *pri, long ap, const char *str) 995 { 996 char *string; 997 unsigned int leng = 0; 998 int ptrsize; 999 long arg = 0; 1000 char *argaddr; 1001 char badaddr[32]; 1002 1003 if (interrupt) 1004 return; 1005 1006 #ifdef _LP64 1007 if (data_model == PR_MODEL_LP64) { 1008 argaddr = (char *)&arg; 1009 ptrsize = 8; 1010 } else { 1011 #if defined(_LITTLE_ENDIAN) 1012 argaddr = (char *)&arg; 1013 #else 1014 argaddr = (char *)&arg + 4; 1015 #endif 1016 ptrsize = 4; 1017 } 1018 #else 1019 argaddr = (char *)&arg; 1020 ptrsize = 4; 1021 #endif 1022 putpname(pri); 1023 (void) fputc(' ', stdout); 1024 (void) fputs(str, stdout); 1025 leng += 1 + strlen(str); 1026 1027 while (!interrupt) { 1028 if (Pread(Proc, argaddr, ptrsize, ap) != ptrsize) { 1029 (void) printf("\n%s\t*** Bad argument list? ***\n", 1030 pri->pname); 1031 return; 1032 } 1033 ap += ptrsize; 1034 1035 if (arg == 0) 1036 break; 1037 string = fetchstring(pri, arg, PATH_MAX); 1038 if (string == NULL) { 1039 (void) sprintf(badaddr, "BadAddress:0x%.8lX", arg); 1040 string = badaddr; 1041 } 1042 if ((leng += strlen(string)) < 63) { 1043 (void) fputc(' ', stdout); 1044 leng++; 1045 } else { 1046 (void) fputc('\n', stdout); 1047 leng = 0; 1048 putpname(pri); 1049 (void) fputs(" ", stdout); 1050 leng += 2 + strlen(string); 1051 } 1052 (void) fputs(string, stdout); 1053 } 1054 (void) fputc('\n', stdout); 1055 } 1056 1057 /* 1058 * Display contents of read() or write() buffer. 1059 */ 1060 void 1061 showbuffer(private_t *pri, long offset, long count) 1062 { 1063 char buffer[320]; 1064 int nbytes; 1065 char *buf; 1066 int n; 1067 1068 while (count > 0 && !interrupt) { 1069 nbytes = (count < sizeof (buffer))? count : sizeof (buffer); 1070 if ((nbytes = Pread(Proc, buffer, nbytes, offset)) <= 0) 1071 break; 1072 count -= nbytes; 1073 offset += nbytes; 1074 buf = buffer; 1075 while (nbytes > 0 && !interrupt) { 1076 char obuf[65]; 1077 1078 n = (nbytes < 32)? nbytes : 32; 1079 showbytes(buf, n, obuf); 1080 1081 putpname(pri); 1082 (void) fputs(" ", stdout); 1083 (void) fputs(obuf, stdout); 1084 (void) fputc('\n', stdout); 1085 nbytes -= n; 1086 buf += n; 1087 } 1088 } 1089 } 1090 1091 void 1092 showbytes(const char *buf, int n, char *obuf) 1093 { 1094 int c; 1095 1096 while (--n >= 0) { 1097 int c1 = '\\'; 1098 int c2; 1099 1100 switch (c = (*buf++ & 0xff)) { 1101 case '\0': 1102 c2 = '0'; 1103 break; 1104 case '\b': 1105 c2 = 'b'; 1106 break; 1107 case '\t': 1108 c2 = 't'; 1109 break; 1110 case '\n': 1111 c2 = 'n'; 1112 break; 1113 case '\v': 1114 c2 = 'v'; 1115 break; 1116 case '\f': 1117 c2 = 'f'; 1118 break; 1119 case '\r': 1120 c2 = 'r'; 1121 break; 1122 default: 1123 if (isprint(c)) { 1124 c1 = ' '; 1125 c2 = c; 1126 } else { 1127 c1 = c>>4; 1128 c1 += (c1 < 10)? '0' : 'A'-10; 1129 c2 = c&0xf; 1130 c2 += (c2 < 10)? '0' : 'A'-10; 1131 } 1132 break; 1133 } 1134 *obuf++ = (char)c1; 1135 *obuf++ = (char)c2; 1136 } 1137 1138 *obuf = '\0'; 1139 } 1140