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.
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.
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]
23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
26 /* Copyright (c) 1988 AT&T */
27 /* All Rights Reserved */
37 #include <sys/types.h>
38 #include <sys/stack.h>
40 #include <sys/isa_defs.h>
49 * Actions to take when process stops.
53 * Function prototypes for static routines in this module.
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 *);
61 * Report an lwp to be sleeping (if true).
64 report_sleeping(private_t
*pri
, int dotrace
)
66 const lwpstatus_t
*Lsp
= pri
->lwpstat
;
67 int sys
= Lsp
->pr_syscall
;
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
);
78 pri
->ErrPriv
= PRIV_NONE
;
79 pri
->Rval1
= pri
->Rval2
= 0;
80 (void) sysentry(pri
, dotrace
);
84 pri
->length
+= printf("%s", pri
->sys_string
);
86 *pri
->sys_string
= '\0';
88 if (Lsp
->pr_flags
& PR_VFORKP
)
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",
98 (void) fputs("(sleeping...)\n", stdout
);
100 if (prismember(&verbose
, sys
)) {
101 int raw
= prismember(&rawout
, sys
);
103 expound(pri
, 0, raw
);
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
115 * It returns a new flag: JOBSTOP or SLEEPING or 0.
118 requested(private_t
*pri
, int flag
, int dotrace
)
120 const lwpstatus_t
*Lsp
= pri
->lwpstat
;
121 int sig
= Lsp
->pr_cursig
;
129 if (dotrace
&& !cflag
&& prismember(&signals
, sig
)) {
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]");
140 (void) printf(" [caught]");
141 (void) fputc('\n', stdout
);
150 report_sleeping(pri
, dotrace
);
158 jobcontrol(private_t
*pri
, int dotrace
)
160 const lwpstatus_t
*Lsp
= pri
->lwpstat
;
161 int sig
= stopsig(pri
);
166 if (dotrace
&& !cflag
&& /* not just counting */
167 prismember(&signals
, sig
)) { /* tracing this signal */
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
);
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.
192 stopsig(private_t
*pri
)
194 const lwpstatus_t
*Lsp
= pri
->lwpstat
;
197 if (Lsp
->pr_flags
& PR_STOPPED
) {
198 switch (Lsp
->pr_why
) {
201 if (sig
< 0 || sig
> PRMAXSIG
)
206 if (Lsp
->pr_action
.sa_handler
== SIG_DFL
) {
207 switch (Lsp
->pr_cursig
) {
214 if (!(Lsp
->pr_flags
& PR_ORPHAN
))
215 sig
= Lsp
->pr_cursig
;
227 signalled(private_t
*pri
, int flag
, int dotrace
)
229 const lwpstatus_t
*Lsp
= pri
->lwpstat
;
230 int sig
= Lsp
->pr_what
;
232 if (sig
<= 0 || sig
> PRMAXSIG
) /* check bounds */
235 if (dotrace
&& cflag
) { /* just counting */
236 (void) mutex_lock(&count_lock
);
238 (void) mutex_unlock(&count_lock
);
241 if (sig
== SIGCONT
&& (flag
== JOBSIG
|| flag
== JOBSTOP
))
242 flag
= requested(pri
, JOBSTOP
, dotrace
);
243 else if ((flag
= jobcontrol(pri
, dotrace
)) == 0 &&
245 prismember(&signals
, sig
)) {
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]");
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
);
276 faulted(private_t
*pri
, int dotrace
)
278 const lwpstatus_t
*Lsp
= pri
->lwpstat
;
279 int flt
= Lsp
->pr_what
;
281 if ((uint_t
)flt
> PRMAXFAULT
|| !prismember(&faults
, flt
) || !dotrace
)
284 (void) mutex_lock(&count_lock
);
286 (void) mutex_unlock(&count_lock
);
288 if (cflag
) /* just counting */
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
]);
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
);
310 * Set up pri->sys_nargs and pri->sys_args[] (syscall args).
313 setupsysargs(private_t
*pri
, int what
)
315 const lwpstatus_t
*Lsp
= pri
->lwpstat
;
320 /* determine whether syscall is indirect */
321 pri
->sys_indirect
= (Lsp
->pr_reg
[R_G1
] == SYS_syscall
)? 1 : 0;
323 pri
->sys_indirect
= 0;
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
);
331 nargs
= Lsp
->pr_nsysarg
;
333 i
< nargs
&& i
< sizeof (pri
->sys_args
) / sizeof (pri
->sys_args
[0]);
335 pri
->sys_args
[i
] = Lsp
->pr_sysarg
[i
];
336 pri
->sys_nargs
= nargs
;
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)
349 * Return TRUE iff syscall is being traced.
352 sysentry(private_t
*pri
, int dotrace
)
354 pid_t pid
= Pstatus(Proc
)->pr_pid
;
355 const lwpstatus_t
*Lsp
= pri
->lwpstat
;
362 const struct systable
*stp
;
363 int what
= Lsp
->pr_what
;
368 /* for reporting sleeping system calls */
369 if (what
== 0 && (Lsp
->pr_flags
& (PR_ASLEEP
|PR_VFORKP
)))
370 what
= Lsp
->pr_syscall
;
372 /* protect ourself from operating system error */
373 if (what
<= 0 || what
> PRMAXSYS
)
377 * Set up the system call arguments (pri->sys_nargs & pri->sys_args[]).
379 setupsysargs(pri
, what
);
380 nargs
= pri
->sys_nargs
;
382 /* get systable entry for this syscall */
383 subcode
= getsubcode(pri
);
384 stp
= subsys(what
, subcode
);
386 if (nargs
> stp
->nargs
)
388 pri
->sys_nargs
= nargs
;
391 * Fetch and remember first argument if it's a string,
392 * or second argument if SYS_openat or SYS_openat64.
394 pri
->sys_valid
= FALSE
;
395 if ((nargs
> 0 && stp
->arg
[0] == STG
) ||
396 (nargs
> 1 && (what
== SYS_openat
|| what
== SYS_openat64
))) {
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.
405 if (Lsp
->pr_why
== PR_SYSEXIT
&& what
== SYS_execve
) {
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
;
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
);
427 (void) Pread(Proc
, &offset32
,
428 sizeof (offset32
), argv
);
432 } else if (stp
->arg
[0] == STG
) {
433 offset
= pri
->sys_args
[0];
435 offset
= pri
->sys_args
[1];
437 if ((s
= fetchstring(pri
, offset
, PATH_MAX
)) != NULL
) {
438 pri
->sys_valid
= TRUE
;
440 /* reallocate if necessary */
441 while (len
>= pri
->sys_psize
) {
443 pri
->sys_path
= my_malloc(pri
->sys_psize
*= 2,
446 (void) strcpy(pri
->sys_path
, s
); /* remember pathname */
450 istraced
= dotrace
&& prismember(&trace
, what
);
451 raw
= prismember(&rawout
, what
);
453 /* force tracing of read/write buffer dump syscalls */
454 if (!istraced
&& nargs
> 2) {
455 int fdp1
= (int)pri
->sys_args
[0] + 1;
458 if (prismember(&readfd
, fdp1
))
460 } else if (ISWRITE(what
)) {
461 if (prismember(&writefd
, fdp1
))
467 if (cflag
|| !istraced
) /* just counting */
468 *pri
->sys_string
= 0;
470 int argprinted
= FALSE
;
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
,
477 for (i
= 0; i
< nargs
; i
++) {
478 arg
= pri
->sys_args
[i
];
481 if (!raw
&& pri
->sys_valid
&&
482 ((i
== 0 && x
== STG
) ||
483 (i
== 1 && (what
== SYS_openat
||
484 what
== SYS_openat64
)))) { /* already fetched */
486 outstring(pri
, ", ");
487 escape_string(pri
, pri
->sys_path
);
489 } else if (x
!= NOV
&& (x
!= HID
|| raw
)) {
491 outstring(pri
, ", ");
493 (*Print
[x
])(pri
, raw
, arg
,
496 (*Print
[x
])(pri
, raw
, arg
);
509 * sysexit() returns non-zero if anything was printed.
512 sysexit(private_t
*pri
, int dotrace
)
514 const lwpstatus_t
*Lsp
= pri
->lwpstat
;
515 int what
= Lsp
->pr_what
;
516 struct syscount
*scp
;
517 const struct systable
*stp
;
522 /* protect ourself from operating system error */
523 if (what
<= 0 || what
> PRMAXSYS
)
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.
531 if (!prismember(&traceeven
, what
)) {
532 (void) Psysexit(Proc
, what
, FALSE
);
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
;
543 case SYS_exit
: /* these are traced on entry */
546 istraced
= dotrace
&& prismember(&trace
, what
);
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
);
555 (void) fputs(pri
->exec_string
, stdout
);
557 pri
->exec_pname
[0] = '\0';
558 pri
->exec_string
[0] = '\0';
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
);
568 istraced
= sysentry(pri
, dotrace
) && dotrace
;
570 if (!cflag
&& istraced
) {
573 pri
->length
+= printf("%s", pri
->sys_string
);
576 *pri
->sys_string
= '\0';
580 /* get systable entry for this syscall */
581 subcode
= getsubcode(pri
);
582 stp
= subsys(what
, subcode
);
584 if (cflag
&& istraced
) {
585 (void) mutex_lock(&count_lock
);
586 scp
= Cp
->syscount
[what
];
587 if (what
== SYS_forksys
&& 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
))
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
);
602 raw
= prismember(&rawout
, what
);
604 if (!cflag
&& istraced
) {
605 if ((what
== SYS_vfork
|| what
== SYS_forksys
) &&
606 pri
->Errno
== 0 && pri
->Rval2
!= 0) {
608 if (strlen(sysname(pri
, what
, raw
? -1 : subcode
)) < 6) {
609 (void) fputc('\t', stdout
);
613 7 + printf("\t(returning as child ...)");
615 if (what
== SYS_lwp_create
&&
616 pri
->Errno
== 0 && pri
->Rval1
== 0) {
619 7 + printf("\t(returning as new lwp ...)");
621 if (pri
->Errno
!= 0 || what
!= SYS_execve
) {
622 /* prepare to print the return code */
624 if (pri
->length
>= 6)
625 (void) fputc(' ', stdout
);
626 for (; pri
->length
< 6; pri
->length
++)
627 (void) fputc('\t', stdout
);
632 if (pri
->Errno
!= 0) { /* error in syscall */
637 const char *ename
= errname(pri
->Errno
);
638 const char *privname
;
640 (void) printf("Err#%d", pri
->Errno
);
642 (void) fputc(' ', stdout
);
643 (void) fputs(ename
, stdout
);
645 switch (pri
->ErrPriv
) {
653 privname
= "MULTIPLE";
659 privname
= priv_getbynum(pri
->ErrPriv
);
662 if (privname
!= NULL
)
663 (void) printf(" [%s]", privname
);
665 (void) fputc('\n', stdout
);
669 /* show arguments on successful exec */
670 if (what
== SYS_execve
) {
671 if (!cflag
&& istraced
)
673 } else if (!cflag
&& istraced
) {
674 const char *fmt
= NULL
;
675 long rv1
= pri
->Rval1
;
676 long rv2
= pri
->Rval2
;
680 * 32-bit system calls return 32-bit values. We
681 * later mask out the upper bits if we want to
682 * print these as unsigned values.
684 if (data_model
== PR_MODEL_ILP32
) {
694 #ifdef _LONG_LONG_LTOH /* first long of a longlong is the low order */
697 fmt
= "= 0x%lX%.8lX";
702 #else /* the other way around */
704 fmt
= "= 0x%lX%.8lX";
707 rv1
= rv2
; /* ugly */
712 if (rv1
& 0xff000000) {
714 if (data_model
== PR_MODEL_ILP32
)
720 case SYS_sigtimedwait
:
723 else if ((fmt
= rawsigname(pri
, rv1
)) != NULL
) {
724 rv1
= (long)fmt
; /* filthy */
730 if (data_model
== PR_MODEL_LP64
) {
731 rv2
= rv1
& 0xffffffff;
739 switch (stp
->rval
[0]) {
742 if (data_model
== PR_MODEL_ILP32
)
749 if (data_model
== PR_MODEL_ILP32
)
756 if (data_model
== PR_MODEL_ILP32
)
763 if (data_model
== PR_MODEL_ILP32
)
774 (void) printf(fmt
, rv1
, rv2
);
776 switch (stp
->rval
[1]) {
782 if (data_model
== PR_MODEL_ILP32
)
789 if (data_model
== PR_MODEL_ILP32
)
796 if (data_model
== PR_MODEL_ILP32
)
803 if (data_model
== PR_MODEL_ILP32
)
814 (void) printf(fmt
, rv2
);
815 (void) fputc('\n', stdout
);
818 if (what
== SYS_vfork
|| what
== SYS_forksys
) {
819 if (pri
->Rval2
== 0) /* child was created */
820 pri
->child
= pri
->Rval1
;
821 else if (cflag
&& istraced
) /* this is the child */
824 if (what
== SYS_lwp_create
&& pri
->Rval1
== 0 &&
825 cflag
&& istraced
) /* this is the created lwp */
829 #define ISREAD(code) \
830 ((code) == SYS_read || (code) == SYS_pread || (code) == SYS_pread64 || \
831 (code) == SYS_recv || (code) == SYS_recvfrom)
832 #define ISWRITE(code) \
833 ((code) == SYS_write || (code) == SYS_pwrite || \
834 (code) == SYS_pwrite64 || (code) == SYS_send || (code) == SYS_sendto)
836 if (!cflag
&& istraced
) {
837 int fdp1
= (int)pri
->sys_args
[0] + 1; /* filedescriptor + 1 */
840 if (what
!= SYS_execve
)
842 if (ISREAD(what
) || ISWRITE(what
)) {
843 if (pri
->iob_buf
[0] != '\0')
844 (void) printf("%s 0x%.8lX: %s\n",
845 pri
->pname
, pri
->sys_args
[1],
851 * Show buffer contents for read()/pread() or write()/pwrite().
852 * IOBSIZE bytes have already been shown;
853 * don't show them again unless there's more.
855 if ((ISREAD(what
) && pri
->Errno
== 0 &&
856 prismember(&readfd
, fdp1
)) ||
857 (ISWRITE(what
) && prismember(&writefd
, fdp1
))) {
858 long nb
= ISWRITE(what
) ? pri
->sys_args
[2] : pri
->Rval1
;
861 /* enter region of lengthy output */
862 if (nb
> MYBUFSIZ
/ 4)
865 showbuffer(pri
, pri
->sys_args
[1], nb
);
867 /* exit region of lengthy output */
868 if (nb
> MYBUFSIZ
/ 4)
875 * Do verbose interpretation if requested.
876 * If buffer contents for read or write have been requested and
877 * this is a readv() or writev(), force verbose interpretation.
879 if (prismember(&verbose
, what
) ||
880 ((what
== SYS_readv
|| what
== SYS_recvmsg
) &&
881 pri
->Errno
== 0 && prismember(&readfd
, fdp1
)) ||
882 ((what
== SYS_writev
|| what
== SYS_sendfilev
||
883 what
== SYS_sendmsg
) &&
884 prismember(&writefd
, fdp1
)))
885 expound(pri
, pri
->Rval1
, raw
);
888 return (!cflag
&& istraced
);
892 showpaths(private_t
*pri
, const struct systable
*stp
)
894 int what
= pri
->lwpstat
->pr_what
;
897 for (i
= 0; i
< pri
->sys_nargs
; i
++) {
898 if (stp
->arg
[i
] == ATC
&& (int)pri
->sys_args
[i
] == AT_FDCWD
) {
899 (void) printf("%s 0x%.8X: AT_FDCWD\n",
900 pri
->pname
, AT_FDCWD
);
901 } else if ((stp
->arg
[i
] == STG
) ||
902 (stp
->arg
[i
] == RST
&& !pri
->Errno
) ||
903 (stp
->arg
[i
] == RLK
&& !pri
->Errno
&& pri
->Rval1
> 0)) {
904 long addr
= pri
->sys_args
[i
];
906 (stp
->arg
[i
] == RLK
)? (int)pri
->Rval1
: PATH_MAX
;
909 if (pri
->sys_valid
&&
910 ((i
== 0 && stp
->arg
[0] == STG
) ||
911 (i
== 1 && (what
== SYS_openat
||
912 what
== SYS_openat64
)))) /* already fetched */
915 s
= fetchstring(pri
, addr
,
916 maxleng
> PATH_MAX
? PATH_MAX
: maxleng
);
919 (void) printf("%s 0x%.8lX: \"%s\"\n",
920 pri
->pname
, addr
, s
);
926 * Display arguments to successful exec().
929 showargs(private_t
*pri
, int raw
)
931 const lwpstatus_t
*Lsp
= pri
->lwpstat
;
938 ptrsize
= (data_model
== PR_MODEL_LP64
)? 8 : 4;
940 #if defined(__i386) || defined(__amd64) /* XX64 */
941 ap
= (long)Lsp
->pr_reg
[R_SP
];
942 fail
= (Pread(Proc
, &nargs
, sizeof (nargs
), ap
) != sizeof (nargs
));
947 if (data_model
== PR_MODEL_LP64
) {
949 ap
= (long)(Lsp
->pr_reg
[R_SP
]) + 16 * sizeof (int64_t)
951 fail
= (Pread(Proc
, &xnargs
, sizeof (xnargs
), ap
) !=
955 ap
= (long)(Lsp
->pr_reg
[R_SP
]) + 16 * sizeof (int32_t);
956 fail
= (Pread(Proc
, &nargs
, sizeof (nargs
), ap
) !=
963 (void) printf("\n%s\t*** Bad argument list? ***\n", pri
->pname
);
967 (void) printf(" argc = %d\n", nargs
);
969 showpaths(pri
, &systable
[SYS_execve
]);
971 show_cred(pri
, FALSE
, FALSE
);
973 if (aflag
|| eflag
) { /* dump args or environment */
975 /* enter region of (potentially) lengthy output */
978 if (aflag
) /* dump the argument list */
979 dumpargs(pri
, ap
, "argv:");
980 ap
+= (nargs
+1) * ptrsize
;
981 if (eflag
) /* dump the environment */
982 dumpargs(pri
, ap
, "envp:");
984 /* exit region of lengthy output */
990 dumpargs(private_t
*pri
, long ap
, const char *str
)
993 unsigned int leng
= 0;
1003 if (data_model
== PR_MODEL_LP64
) {
1004 argaddr
= (char *)&arg
;
1007 #if defined(_LITTLE_ENDIAN)
1008 argaddr
= (char *)&arg
;
1010 argaddr
= (char *)&arg
+ 4;
1015 argaddr
= (char *)&arg
;
1019 (void) fputc(' ', stdout
);
1020 (void) fputs(str
, stdout
);
1021 leng
+= 1 + strlen(str
);
1023 while (!interrupt
) {
1024 if (Pread(Proc
, argaddr
, ptrsize
, ap
) != ptrsize
) {
1025 (void) printf("\n%s\t*** Bad argument list? ***\n",
1033 string
= fetchstring(pri
, arg
, PATH_MAX
);
1034 if (string
== NULL
) {
1035 (void) sprintf(badaddr
, "BadAddress:0x%.8lX", arg
);
1038 if ((leng
+= strlen(string
)) < 63) {
1039 (void) fputc(' ', stdout
);
1042 (void) fputc('\n', stdout
);
1045 (void) fputs(" ", stdout
);
1046 leng
+= 2 + strlen(string
);
1048 (void) fputs(string
, stdout
);
1050 (void) fputc('\n', stdout
);
1054 * Display contents of read() or write() buffer.
1057 showbuffer(private_t
*pri
, long offset
, long count
)
1064 while (count
> 0 && !interrupt
) {
1065 nbytes
= (count
< sizeof (buffer
))? count
: sizeof (buffer
);
1066 if ((nbytes
= Pread(Proc
, buffer
, nbytes
, offset
)) <= 0)
1071 while (nbytes
> 0 && !interrupt
) {
1074 n
= (nbytes
< 32)? nbytes
: 32;
1075 showbytes(buf
, n
, obuf
);
1078 (void) fputs(" ", stdout
);
1079 (void) fputs(obuf
, stdout
);
1080 (void) fputc('\n', stdout
);
1088 showbytes(const char *buf
, int n
, char *obuf
)
1096 switch (c
= (*buf
++ & 0xff)) {
1124 c1
+= (c1
< 10)? '0' : 'A'-10;
1126 c2
+= (c2
< 10)? '0' : 'A'-10;