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