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