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