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 /* 679 * 32-bit system calls return 32-bit values. We 680 * later mask out the upper bits if we want to 681 * print these as unsigned values. 682 */ 683 if (data_model == PR_MODEL_ILP32) { 684 rv1 = (int)rv1; 685 rv2 = (int)rv2; 686 } 687 688 switch (what) { 689 case SYS_llseek: 690 rv1 &= 0xffffffff; 691 rv2 &= 0xffffffff; 692 #ifdef _LONG_LONG_LTOH /* first long of a longlong is the low order */ 693 if (rv2 != 0) { 694 long temp = rv1; 695 fmt = "= 0x%lX%.8lX"; 696 rv1 = rv2; 697 rv2 = temp; 698 break; 699 } 700 #else /* the other way around */ 701 if (rv1 != 0) { 702 fmt = "= 0x%lX%.8lX"; 703 break; 704 } 705 rv1 = rv2; /* ugly */ 706 #endif 707 /* FALLTHROUGH */ 708 case SYS_lseek: 709 case SYS_ulimit: 710 if (rv1 & 0xff000000) { 711 if (data_model == PR_MODEL_ILP32) 712 rv1 &= 0xffffffff; 713 fmt = "= 0x%.8lX"; 714 } 715 break; 716 case SYS_sigtimedwait: 717 if (raw) 718 /* EMPTY */; 719 else if ((fmt = rawsigname(pri, rv1)) != NULL) { 720 rv1 = (long)fmt; /* filthy */ 721 fmt = "= %s"; 722 } 723 break; 724 case SYS_port: 725 if (data_model == PR_MODEL_LP64) { 726 rv2 = rv1 & 0xffffffff; 727 rv1 = rv1 >> 32; 728 } 729 break; 730 } 731 732 if (fmt == NULL) { 733 switch (stp->rval[0]) { 734 case HEX: 735 if (data_model == PR_MODEL_ILP32) 736 rv1 &= 0xffffffff; 737 fmt = "= 0x%.8lX"; 738 break; 739 case HHX: 740 if (data_model == PR_MODEL_ILP32) 741 rv1 &= 0xffffffff; 742 fmt = "= 0x%.4lX"; 743 break; 744 case OCT: 745 if (data_model == PR_MODEL_ILP32) 746 rv1 &= 0xffffffff; 747 fmt = "= %#lo"; 748 break; 749 case UNS: 750 if (data_model == PR_MODEL_ILP32) 751 rv1 &= 0xffffffff; 752 fmt = "= %lu"; 753 break; 754 default: 755 fmt = "= %ld"; 756 break; 757 } 758 } 759 760 (void) printf(fmt, rv1, rv2); 761 762 switch (stp->rval[1]) { 763 case NOV: 764 fmt = NULL; 765 break; 766 case HEX: 767 if (data_model == PR_MODEL_ILP32) 768 rv2 &= 0xffffffff; 769 fmt = " [0x%.8lX]"; 770 break; 771 case HHX: 772 if (data_model == PR_MODEL_ILP32) 773 rv2 &= 0xffffffff; 774 fmt = " [0x%.4lX]"; 775 break; 776 case OCT: 777 if (data_model == PR_MODEL_ILP32) 778 rv2 &= 0xffffffff; 779 fmt = " [%#lo]"; 780 break; 781 case UNS: 782 if (data_model == PR_MODEL_ILP32) 783 rv2 &= 0xffffffff; 784 fmt = " [%lu]"; 785 break; 786 default: 787 fmt = " [%ld]"; 788 break; 789 } 790 791 if (fmt != NULL) 792 (void) printf(fmt, rv2); 793 (void) fputc('\n', stdout); 794 } 795 796 if (what == SYS_vfork || what == SYS_forksys) { 797 if (pri->Rval2 == 0) /* child was created */ 798 pri->child = pri->Rval1; 799 else if (cflag && istraced) /* this is the child */ 800 scp->count--; 801 } 802 if (what == SYS_lwp_create && pri->Rval1 == 0 && 803 cflag && istraced) /* this is the created lwp */ 804 scp->count--; 805 } 806 807 #define ISREAD(code) \ 808 ((code) == SYS_read || (code) == SYS_pread || (code) == SYS_pread64 || \ 809 (code) == SYS_recv || (code) == SYS_recvfrom) 810 #define ISWRITE(code) \ 811 ((code) == SYS_write || (code) == SYS_pwrite || \ 812 (code) == SYS_pwrite64 || (code) == SYS_send || (code) == SYS_sendto) 813 814 if (!cflag && istraced) { 815 int fdp1 = (int)pri->sys_args[0] + 1; /* filedescriptor + 1 */ 816 817 if (raw) { 818 if (what != SYS_execve) 819 showpaths(pri, stp); 820 if (ISREAD(what) || ISWRITE(what)) { 821 if (pri->iob_buf[0] != '\0') 822 (void) printf("%s 0x%.8lX: %s\n", 823 pri->pname, pri->sys_args[1], 824 pri->iob_buf); 825 } 826 } 827 828 /* 829 * Show buffer contents for read()/pread() or write()/pwrite(). 830 * IOBSIZE bytes have already been shown; 831 * don't show them again unless there's more. 832 */ 833 if ((ISREAD(what) && pri->Errno == 0 && 834 prismember(&readfd, fdp1)) || 835 (ISWRITE(what) && prismember(&writefd, fdp1))) { 836 long nb = ISWRITE(what) ? pri->sys_args[2] : pri->Rval1; 837 838 if (nb > IOBSIZE) { 839 /* enter region of lengthy output */ 840 if (nb > MYBUFSIZ / 4) 841 Eserialize(); 842 843 showbuffer(pri, pri->sys_args[1], nb); 844 845 /* exit region of lengthy output */ 846 if (nb > MYBUFSIZ / 4) 847 Xserialize(); 848 } 849 } 850 #undef ISREAD 851 #undef ISWRITE 852 /* 853 * Do verbose interpretation if requested. 854 * If buffer contents for read or write have been requested and 855 * this is a readv() or writev(), force verbose interpretation. 856 */ 857 if (prismember(&verbose, what) || 858 ((what == SYS_readv || what == SYS_recvmsg) && 859 pri->Errno == 0 && prismember(&readfd, fdp1)) || 860 ((what == SYS_writev || what == SYS_sendfilev || 861 what == SYS_sendmsg) && 862 prismember(&writefd, fdp1))) 863 expound(pri, pri->Rval1, raw); 864 } 865 866 return (!cflag && istraced); 867 } 868 869 void 870 showpaths(private_t *pri, const struct systable *stp) 871 { 872 int what = pri->lwpstat->pr_what; 873 int i; 874 875 for (i = 0; i < pri->sys_nargs; i++) { 876 if (stp->arg[i] == ATC && (int)pri->sys_args[i] == AT_FDCWD) { 877 (void) printf("%s 0x%.8X: AT_FDCWD\n", 878 pri->pname, AT_FDCWD); 879 } else if ((stp->arg[i] == STG) || 880 (stp->arg[i] == RST && !pri->Errno) || 881 (stp->arg[i] == RLK && !pri->Errno && pri->Rval1 > 0)) { 882 long addr = pri->sys_args[i]; 883 int maxleng = 884 (stp->arg[i] == RLK)? (int)pri->Rval1 : PATH_MAX; 885 char *s; 886 887 if (pri->sys_valid && 888 ((i == 0 && stp->arg[0] == STG) || 889 (i == 1 && (what == SYS_openat || 890 what == SYS_openat64)))) /* already fetched */ 891 s = pri->sys_path; 892 else 893 s = fetchstring(pri, addr, 894 maxleng > PATH_MAX ? PATH_MAX : maxleng); 895 896 if (s != (char *)NULL) 897 (void) printf("%s 0x%.8lX: \"%s\"\n", 898 pri->pname, addr, s); 899 } 900 } 901 } 902 903 /* 904 * Display arguments to successful exec(). 905 */ 906 void 907 showargs(private_t *pri, int raw) 908 { 909 const lwpstatus_t *Lsp = pri->lwpstat; 910 int nargs; 911 long ap; 912 int ptrsize; 913 int fail; 914 915 pri->length = 0; 916 ptrsize = (data_model == PR_MODEL_LP64)? 8 : 4; 917 918 #if defined(__i386) || defined(__amd64) /* XX64 */ 919 ap = (long)Lsp->pr_reg[R_SP]; 920 fail = (Pread(Proc, &nargs, sizeof (nargs), ap) != sizeof (nargs)); 921 ap += ptrsize; 922 #endif /* i386 */ 923 924 #if sparc 925 if (data_model == PR_MODEL_LP64) { 926 int64_t xnargs; 927 ap = (long)(Lsp->pr_reg[R_SP]) + 16 * sizeof (int64_t) 928 + STACK_BIAS; 929 fail = (Pread(Proc, &xnargs, sizeof (xnargs), ap) != 930 sizeof (xnargs)); 931 nargs = (int)xnargs; 932 } else { 933 ap = (long)(Lsp->pr_reg[R_SP]) + 16 * sizeof (int32_t); 934 fail = (Pread(Proc, &nargs, sizeof (nargs), ap) != 935 sizeof (nargs)); 936 } 937 ap += ptrsize; 938 #endif /* sparc */ 939 940 if (fail) { 941 (void) printf("\n%s\t*** Bad argument list? ***\n", pri->pname); 942 return; 943 } 944 945 (void) printf(" argc = %d\n", nargs); 946 if (raw) 947 showpaths(pri, &systable[SYS_execve]); 948 949 show_cred(pri, FALSE, FALSE); 950 951 if (aflag || eflag) { /* dump args or environment */ 952 953 /* enter region of (potentially) lengthy output */ 954 Eserialize(); 955 956 if (aflag) /* dump the argument list */ 957 dumpargs(pri, ap, "argv:"); 958 ap += (nargs+1) * ptrsize; 959 if (eflag) /* dump the environment */ 960 dumpargs(pri, ap, "envp:"); 961 962 /* exit region of lengthy output */ 963 Xserialize(); 964 } 965 } 966 967 void 968 dumpargs(private_t *pri, long ap, const char *str) 969 { 970 char *string; 971 unsigned int leng = 0; 972 int ptrsize; 973 long arg = 0; 974 char *argaddr; 975 char badaddr[32]; 976 977 if (interrupt) 978 return; 979 980 if (data_model == PR_MODEL_LP64) { 981 argaddr = (char *)&arg; 982 ptrsize = 8; 983 } else { 984 #if defined(_LITTLE_ENDIAN) 985 argaddr = (char *)&arg; 986 #else 987 argaddr = (char *)&arg + 4; 988 #endif 989 ptrsize = 4; 990 } 991 putpname(pri); 992 (void) fputc(' ', stdout); 993 (void) fputs(str, stdout); 994 leng += 1 + strlen(str); 995 996 while (!interrupt) { 997 if (Pread(Proc, argaddr, ptrsize, ap) != ptrsize) { 998 (void) printf("\n%s\t*** Bad argument list? ***\n", 999 pri->pname); 1000 return; 1001 } 1002 ap += ptrsize; 1003 1004 if (arg == 0) 1005 break; 1006 string = fetchstring(pri, arg, PATH_MAX); 1007 if (string == NULL) { 1008 (void) sprintf(badaddr, "BadAddress:0x%.8lX", arg); 1009 string = badaddr; 1010 } 1011 if ((leng += strlen(string)) < 63) { 1012 (void) fputc(' ', stdout); 1013 leng++; 1014 } else { 1015 (void) fputc('\n', stdout); 1016 leng = 0; 1017 putpname(pri); 1018 (void) fputs(" ", stdout); 1019 leng += 2 + strlen(string); 1020 } 1021 (void) fputs(string, stdout); 1022 } 1023 (void) fputc('\n', stdout); 1024 } 1025 1026 /* 1027 * Display contents of read() or write() buffer. 1028 */ 1029 void 1030 showbuffer(private_t *pri, long offset, long count) 1031 { 1032 char buffer[320]; 1033 int nbytes; 1034 char *buf; 1035 int n; 1036 1037 while (count > 0 && !interrupt) { 1038 nbytes = (count < sizeof (buffer))? count : sizeof (buffer); 1039 if ((nbytes = Pread(Proc, buffer, nbytes, offset)) <= 0) 1040 break; 1041 count -= nbytes; 1042 offset += nbytes; 1043 buf = buffer; 1044 while (nbytes > 0 && !interrupt) { 1045 char obuf[65]; 1046 1047 n = (nbytes < 32)? nbytes : 32; 1048 showbytes(buf, n, obuf); 1049 1050 putpname(pri); 1051 (void) fputs(" ", stdout); 1052 (void) fputs(obuf, stdout); 1053 (void) fputc('\n', stdout); 1054 nbytes -= n; 1055 buf += n; 1056 } 1057 } 1058 } 1059 1060 void 1061 showbytes(const char *buf, int n, char *obuf) 1062 { 1063 int c; 1064 1065 while (--n >= 0) { 1066 int c1 = '\\'; 1067 int c2; 1068 1069 switch (c = (*buf++ & 0xff)) { 1070 case '\0': 1071 c2 = '0'; 1072 break; 1073 case '\b': 1074 c2 = 'b'; 1075 break; 1076 case '\t': 1077 c2 = 't'; 1078 break; 1079 case '\n': 1080 c2 = 'n'; 1081 break; 1082 case '\v': 1083 c2 = 'v'; 1084 break; 1085 case '\f': 1086 c2 = 'f'; 1087 break; 1088 case '\r': 1089 c2 = 'r'; 1090 break; 1091 default: 1092 if (isprint(c)) { 1093 c1 = ' '; 1094 c2 = c; 1095 } else { 1096 c1 = c>>4; 1097 c1 += (c1 < 10)? '0' : 'A'-10; 1098 c2 = c&0xf; 1099 c2 += (c2 < 10)? '0' : 'A'-10; 1100 } 1101 break; 1102 } 1103 *obuf++ = (char)c1; 1104 *obuf++ = (char)c2; 1105 } 1106 1107 *obuf = '\0'; 1108 } 1109