Пример #1
0
static int
look(char *arg)
{
	int gcode;
	int gcode2;
	pstatus_t pstatus;
	psinfo_t psinfo;
	int flags;
	sigset_t sigmask;
	fltset_t fltmask;
	sysset_t entryset;
	sysset_t exitset;
	uint32_t sigtrace, sigtrace1, sigtrace2, fltbits;
	uint32_t sigpend, sigpend1, sigpend2;
	uint32_t *bits;
	char buf[PRSIGBUFSZ];
	look_arg_t lookarg;

	if ((Pr = proc_arg_xgrab(arg, NULL, PR_ARG_ANY,
	    PGRAB_RETAIN | PGRAB_FORCE | PGRAB_RDONLY | PGRAB_NOSTOP, &gcode,
	    &lookarg.lwps)) == NULL) {
		if (gcode == G_NOPROC &&
		    proc_arg_psinfo(arg, PR_ARG_PIDS, &psinfo, &gcode2) > 0 &&
		    psinfo.pr_nlwp == 0) {
			(void) printf("%d:\t<defunct>\n\n", (int)psinfo.pr_pid);
			return (0);
		}
		(void) fprintf(stderr, "%s: cannot examine %s: %s\n",
		    command, arg, Pgrab_error(gcode));
		return (1);
	}

	(void) memcpy(&pstatus, Pstatus(Pr), sizeof (pstatus_t));
	(void) memcpy(&psinfo, Ppsinfo(Pr), sizeof (psinfo_t));
	proc_unctrl_psinfo(&psinfo);

	if (psinfo.pr_nlwp == 0) {
		(void) printf("%d:\t<defunct>\n\n", (int)psinfo.pr_pid);
		Prelease(Pr, PRELEASE_RETAIN);
		return (0);
	}

	is64 = (pstatus.pr_dmodel == PR_MODEL_LP64);

	sigmask = pstatus.pr_sigtrace;
	fltmask = pstatus.pr_flttrace;
	entryset = pstatus.pr_sysentry;
	exitset = pstatus.pr_sysexit;

	if (Pstate(Pr) == PS_DEAD) {
		(void) printf("core '%s' of %d:\t%.70s\n",
		    arg, (int)psinfo.pr_pid, psinfo.pr_psargs);
	} else {
		(void) printf("%d:\t%.70s\n",
		    (int)psinfo.pr_pid, psinfo.pr_psargs);
	}

	(void) printf("\tdata model = %s", is64? "_LP64" : "_ILP32");
	if ((flags = (pstatus.pr_flags & PROCFLAGS)) != 0)
		(void) printf("  flags = %s", prflags(flags));
	(void) printf("\n");

	fltbits = *((uint32_t *)&fltmask);
	if (fltbits)
		(void) printf("\tflttrace = 0x%.8x\n", fltbits);

#if (MAXSIG > 2 * 32) && (MAXSIG <= 3 * 32)	/* assumption */
	sigtrace = *((uint32_t *)&sigmask);
	sigtrace1 = *((uint32_t *)&sigmask + 1);
	sigtrace2 = *((uint32_t *)&sigmask + 2);
#else
#error "fix me: MAXSIG out of bounds"
#endif
	if (sigtrace | sigtrace1 | sigtrace2)
		(void) printf("\tsigtrace = 0x%.8x 0x%.8x 0x%.8x\n\t    %s\n",
		    sigtrace, sigtrace1, sigtrace2,
		    proc_sigset2str(&sigmask, "|", 1, buf, sizeof (buf)));

	bits = ((uint32_t *)&entryset);
	if (bits[0] | bits[1] | bits[2] | bits[3] |
	    bits[4] | bits[5] | bits[6] | bits[7])
		(void) printf(
		    "\tentryset = "
		    "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
		    "\t           "
		    "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
		    bits[0], bits[1], bits[2], bits[3],
		    bits[4], bits[5], bits[6], bits[7]);

	bits = ((uint32_t *)&exitset);
	if (bits[0] | bits[1] | bits[2] | bits[3] |
	    bits[4] | bits[5] | bits[6] | bits[7])
		(void) printf(
		    "\texitset  = "
		    "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
		    "\t           "
		    "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
		    bits[0], bits[1], bits[2], bits[3],
		    bits[4], bits[5], bits[6], bits[7]);

#if (MAXSIG > 2 * 32) && (MAXSIG <= 3 * 32)	/* assumption */
	sigpend  = *((uint32_t *)&pstatus.pr_sigpend);
	sigpend1 = *((uint32_t *)&pstatus.pr_sigpend + 1);
	sigpend2 = *((uint32_t *)&pstatus.pr_sigpend + 2);
#else
#error "fix me: MAXSIG out of bounds"
#endif
	if (sigpend | sigpend1 | sigpend2)
		(void) printf("\tsigpend = 0x%.8x,0x%.8x,0x%.8x\n",
		    sigpend, sigpend1, sigpend2);

	lookarg.pflags = pstatus.pr_flags;
	lookarg.count = 0;
	(void) Plwp_iter_all(Pr, (proc_lwp_all_f *)lwplook, &lookarg);

	if (lookarg.count == 0)
		(void) printf("No matching lwps found");

	(void) printf("\n");
	Prelease(Pr, PRELEASE_RETAIN);

	return (0);
}
Пример #2
0
int
main(int argc, char **argv)
{
    int rflag = 0, sflag = 0, xflag = 0, Fflag = 0;
    int errflg = 0, Sflag = 0;
    int rc = 0;
    int opt;
    const char *bar8 = "-------";
    const char *bar16 = "----------";
    const char *bar;
    struct rlimit rlim;
    struct stat64 statbuf;
    char buf[128];
    int mapfd;
    int prg_gflags = PGRAB_RDONLY;
    int prr_flags = 0;
    boolean_t use_agent_lwp = B_FALSE;

    if ((command = strrchr(argv[0], '/')) != NULL)
        command++;
    else
        command = argv[0];

    while ((opt = getopt(argc, argv, "arsxSlLFA:")) != EOF) {
        switch (opt) {
        case 'a':		/* include shared mappings in -[xS] */
            aflag = 1;
            break;
        case 'r':		/* show reserved mappings */
            rflag = 1;
            break;
        case 's':		/* show hardware page sizes */
            sflag = 1;
            break;
        case 'S':		/* show swap reservations */
            Sflag = 1;
            break;
        case 'x':		/* show extended mappings */
            xflag = 1;
            break;
        case 'l':		/* show unresolved link map names */
            lflag = 1;
            break;
        case 'L':		/* show lgroup information */
            Lflag = 1;
            use_agent_lwp = B_TRUE;
            break;
        case 'F':		/* force grabbing (no O_EXCL) */
            Fflag = PGRAB_FORCE;
            break;
        case 'A':
            if (parse_addr_range(optarg, &start_addr, &end_addr)
                    != 0)
                errflg++;
            break;
        default:
            errflg = 1;
            break;
        }
    }

    argc -= optind;
    argv += optind;

    if ((Sflag && (xflag || rflag || sflag)) || (xflag && rflag) ||
            (aflag && (!xflag && !Sflag)) ||
            (Lflag && (xflag || Sflag))) {
        errflg = 1;
    }

    if (errflg || argc <= 0) {
        (void) fprintf(stderr,
                       "usage:\t%s [-rslF] [-A start[,end]] { pid | core } ...\n",
                       command);
        (void) fprintf(stderr,
                       "\t\t(report process address maps)\n");
        (void) fprintf(stderr,
                       "\t%s -L [-rslF] [-A start[,end]] pid ...\n", command);
        (void) fprintf(stderr,
                       "\t\t(report process address maps lgroups mappings)\n");
        (void) fprintf(stderr,
                       "\t%s -x [-aslF] [-A start[,end]] pid ...\n", command);
        (void) fprintf(stderr,
                       "\t\t(show resident/anon/locked mapping details)\n");
        (void) fprintf(stderr,
                       "\t%s -S [-alF] [-A start[,end]] { pid | core } ...\n",
                       command);
        (void) fprintf(stderr,
                       "\t\t(show swap reservations)\n\n");
        (void) fprintf(stderr,
                       "\t-a: include shared mappings in -[xS] summary\n");
        (void) fprintf(stderr,
                       "\t-r: show reserved address maps\n");
        (void) fprintf(stderr,
                       "\t-s: show hardware page sizes\n");
        (void) fprintf(stderr,
                       "\t-l: show unresolved dynamic linker map names\n");
        (void) fprintf(stderr,
                       "\t-F: force grabbing of the target process\n");
        (void) fprintf(stderr,
                       "\t-L: show lgroup mappings\n");
        (void) fprintf(stderr,
                       "\t-A start,end: limit output to the specified range\n");
        return (2);
    }

    /*
     * Make sure we'll have enough file descriptors to handle a target
     * that has many many mappings.
     */
    if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
        rlim.rlim_cur = rlim.rlim_max;
        (void) setrlimit(RLIMIT_NOFILE, &rlim);
        (void) enable_extended_FILE_stdio(-1, -1);
    }

    /*
     * The implementation of -L option creates an agent LWP in the target
     * process address space. The agent LWP issues meminfo(2) system calls
     * on behalf of the target process. If we are interrupted prematurely,
     * the target process remains in the stopped state with the agent still
     * attached to it. To prevent such situation we catch signals from
     * terminal and terminate gracefully.
     */
    if (use_agent_lwp) {
        /*
         * Buffer output to stdout, stderr while process is grabbed.
         * Prevents infamous deadlocks due to pmap `pgrep xterm` and
         * other variants.
         */
        (void) proc_initstdio();

        prg_gflags = PGRAB_RETAIN | Fflag;
        prr_flags = PRELEASE_RETAIN;

        if (sigset(SIGHUP, SIG_IGN) == SIG_DFL)
            (void) sigset(SIGHUP, intr);
        if (sigset(SIGINT, SIG_IGN) == SIG_DFL)
            (void) sigset(SIGINT, intr);
        if (sigset(SIGQUIT, SIG_IGN) == SIG_DFL)
            (void) sigset(SIGQUIT, intr);
        (void) sigset(SIGPIPE, intr);
        (void) sigset(SIGTERM, intr);
    }

    while (argc-- > 0) {
        char *arg;
        int gcode;
        psinfo_t psinfo;
        int tries = 0;

        if (use_agent_lwp)
            (void) proc_flushstdio();

        if ((Pr = proc_arg_grab(arg = *argv++, PR_ARG_ANY,
                                prg_gflags, &gcode)) == NULL) {
            (void) fprintf(stderr, "%s: cannot examine %s: %s\n",
                           command, arg, Pgrab_error(gcode));
            rc++;
            continue;
        }

        procname = arg;		/* for perr() */

        addr_width = (Pstatus(Pr)->pr_dmodel == PR_MODEL_LP64) ? 16 : 8;
        size_width = (Pstatus(Pr)->pr_dmodel == PR_MODEL_LP64) ? 11 : 8;
        bar = addr_width == 8 ? bar8 : bar16;
        (void) memcpy(&psinfo, Ppsinfo(Pr), sizeof (psinfo_t));
        proc_unctrl_psinfo(&psinfo);

        if (Pstate(Pr) != PS_DEAD) {
            (void) snprintf(buf, sizeof (buf),
                            "/proc/%d/map", (int)psinfo.pr_pid);
            if ((mapfd = open(buf, O_RDONLY)) < 0) {
                (void) fprintf(stderr, "%s: cannot "
                               "examine %s: lost control of "
                               "process\n", command, arg);
                rc++;
                Prelease(Pr, prr_flags);
                continue;
            }
        } else {
            mapfd = -1;
        }

again:
        map_count = 0;

        if (Pstate(Pr) == PS_DEAD) {
            (void) printf("core '%s' of %d:\t%.70s\n",
                          arg, (int)psinfo.pr_pid, psinfo.pr_psargs);

            if (rflag || sflag || xflag || Sflag || Lflag) {
                (void) printf("  -%c option is not compatible "
                              "with core files\n", xflag ? 'x' :
                              sflag ? 's' : rflag ? 'r' :
                              Lflag ? 'L' : 'S');
                Prelease(Pr, prr_flags);
                rc++;
                continue;
            }

        } else {
            (void) printf("%d:\t%.70s\n",
                          (int)psinfo.pr_pid, psinfo.pr_psargs);
        }

        if (!(Pstatus(Pr)->pr_flags & PR_ISSYS)) {
            struct totals t;

            /*
             * Since we're grabbing the process readonly, we need
             * to make sure the address space doesn't change during
             * execution.
             */
            if (Pstate(Pr) != PS_DEAD) {
                if (tries++ == MAX_TRIES) {
                    Prelease(Pr, prr_flags);
                    (void) close(mapfd);
                    (void) fprintf(stderr, "%s: cannot "
                                   "examine %s: address space is "
                                   "changing\n", command, arg);
                    continue;
                }

                if (fstat64(mapfd, &statbuf) != 0) {
                    Prelease(Pr, prr_flags);
                    (void) close(mapfd);
                    (void) fprintf(stderr, "%s: cannot "
                                   "examine %s: lost control of "
                                   "process\n", command, arg);
                    continue;
                }
            }

            nstacks = psinfo.pr_nlwp * 2;
            stacks = calloc(nstacks, sizeof (stacks[0]));
            if (stacks != NULL) {
                int n = 0;
                (void) Plwp_iter(Pr, getstack, &n);
                qsort(stacks, nstacks, sizeof (stacks[0]),
                      cmpstacks);
            }

            (void) memset(&t, 0, sizeof (t));

            if (Pgetauxval(Pr, AT_BASE) != -1L &&
                    Prd_agent(Pr) == NULL) {
                (void) fprintf(stderr, "%s: warning: "
                               "librtld_db failed to initialize; "
                               "shared library information will not be "
                               "available\n", command);
            }

            /*
             * Gather data
             */
            if (xflag)
                rc += xmapping_iter(Pr, gather_xmap, NULL, 0);
            else if (Sflag)
                rc += xmapping_iter(Pr, gather_xmap, NULL, 1);
            else {
                if (rflag)
                    rc += rmapping_iter(Pr, gather_map,
                                        NULL);
                else if (sflag)
                    rc += xmapping_iter(Pr, gather_xmap,
                                        NULL, 0);
                else if (lflag)
                    rc += Pmapping_iter(Pr,
                                        gather_map, NULL);
                else
                    rc += Pmapping_iter_resolved(Pr,
                                                 gather_map, NULL);
            }

            /*
             * Ensure mappings are consistent.
             */
            if (Pstate(Pr) != PS_DEAD) {
                struct stat64 newbuf;

                if (fstat64(mapfd, &newbuf) != 0 ||
                        memcmp(&newbuf.st_mtim, &statbuf.st_mtim,
                               sizeof (newbuf.st_mtim)) != 0) {
                    if (stacks != NULL) {
                        free(stacks);
                        stacks = NULL;
                    }
                    goto again;
                }
            }

            /*
             * Display data.
             */
            if (xflag) {
                (void) printf("%*s%*s%*s%*s%*s "
                              "%sMode   Mapped File\n",
                              addr_width, "Address",
                              size_width, "Kbytes",
                              size_width, "RSS",
                              size_width, "Anon",
                              size_width, "Locked",
                              sflag ? "Pgsz " : "");

                rc += iter_xmap(sflag ?  look_xmap :
                                look_xmap_nopgsz, &t);

                (void) printf("%s%s %s %s %s %s\n",
                              addr_width == 8 ? "-" : "------",
                              bar, bar, bar, bar, bar);

                (void) printf("%stotal Kb", addr_width == 16 ?
                              "        " : "");

                printK(t.total_size, size_width);
                printK(t.total_rss, size_width);
                printK(t.total_anon, size_width);
                printK(t.total_locked, size_width);

                (void) printf("\n");

            } else if (Sflag) {
                (void) printf("%*s%*s%*s Mode"
                              " Mapped File\n",
                              addr_width, "Address",
                              size_width, "Kbytes",
                              size_width, "Swap");

                rc += iter_xmap(look_xmap_nopgsz, &t);

                (void) printf("%s%s %s %s\n",
                              addr_width == 8 ? "-" : "------",
                              bar, bar, bar);

                (void) printf("%stotal Kb", addr_width == 16 ?
                              "        " : "");

                printK(t.total_size, size_width);
                printK(t.total_swap, size_width);

                (void) printf("\n");

            } else {

                if (rflag) {
                    rc += iter_map(look_map, &t);
                } else if (sflag) {
                    if (Lflag) {
                        (void) printf("%*s %*s %4s"
                                      " %-6s %s %s\n",
                                      addr_width, "Address",
                                      size_width,
                                      "Bytes", "Pgsz", "Mode ",
                                      "Lgrp", "Mapped File");
                        rc += iter_xmap(look_smap, &t);
                    } else {
                        (void) printf("%*s %*s %4s"
                                      " %-6s %s\n",
                                      addr_width, "Address",
                                      size_width,
                                      "Bytes", "Pgsz", "Mode ",
                                      "Mapped File");
                        rc += iter_xmap(look_smap, &t);
                    }
                } else {
                    rc += iter_map(look_map, &t);
                }

                (void) printf(" %stotal  %*luK\n",
                              addr_width == 16 ?
                              "        " : "",
                              size_width, t.total_size);
            }

            if (stacks != NULL) {
                free(stacks);
                stacks = NULL;
            }

        }

        Prelease(Pr, prr_flags);
        if (mapfd != -1)
            (void) close(mapfd);
    }

    if (use_agent_lwp)
        (void) proc_finistdio();

    return (rc);
}
Пример #3
0
int
main(int argc, char **argv)
{
	secflagdelta_t act;
	psecflagwhich_t which = PSF_INHERIT;
	int ret = 0;
	int pgrab_flags = PGRAB_RDONLY;
	int opt;
	char *idtypename = NULL;
	idtype_t idtype = P_PID;
	boolean_t usage = B_FALSE;
	boolean_t e_flag = B_FALSE;
	boolean_t l_flag = B_FALSE;
	boolean_t s_flag = B_FALSE;
	int errc = 0;

	while ((opt = getopt(argc, argv, "eFi:ls:")) != -1) {
		switch (opt) {
		case 'e':
			e_flag = B_TRUE;
			break;
		case 'F':
			pgrab_flags |= PGRAB_FORCE;
			break;
		case 'i':
			idtypename = optarg;
			break;
		case 's':
			s_flag = B_TRUE;
			if ((strlen(optarg) >= 2) &&
			    ((optarg[1] == '='))) {
				switch (optarg[0]) {
				case 'L':
					which = PSF_LOWER;
					break;
				case 'U':
					which = PSF_UPPER;
					break;
				case 'I':
					which = PSF_INHERIT;
					break;
				case 'E':
					errx(1, "the effective flags cannot "
					    "be changed", optarg[0]);
				default:
					errx(1, "unknown security flag "
					    "set: '%c'", optarg[0]);
				}

				optarg += 2;
			}

			if (secflags_parse(NULL, optarg, &act) == -1)
				errx(1, "couldn't parse security flags: %s",
				    optarg);
			break;
		case 'l':
			l_flag = B_TRUE;
			break;
		default:
			usage = B_TRUE;
			break;
		}
	}

	argc -= optind;
	argv += optind;

	if (l_flag && ((idtypename != NULL) || s_flag || (argc != 0)))
		usage = B_TRUE;
	if ((idtypename != NULL) && !s_flag)
		usage = B_TRUE;
	if (e_flag && !s_flag)
		usage = B_TRUE;
	if (!l_flag && argc <= 0)
		usage = B_TRUE;

	if (usage) {
		(void) fprintf(stderr,
		    gettext("usage:\t%s [-F] { pid | core } ...\n"),
		    __progname);
		(void) fprintf(stderr,
		    gettext("\t%s -s spec [-i idtype] id ...\n"),
		    __progname);
		(void) fprintf(stderr,
		    gettext("\t%s -s spec -e command [arg]...\n"),
		    __progname);
		(void) fprintf(stderr, gettext("\t%s -l\n"), __progname);
		return (2);
	}

	if (l_flag) {
		secflag_t i;
		const char *name;

		for (i = 0; (name = secflag_to_str(i)) != NULL; i++)
			(void) printf("%s\n", name);
		return (0);
	} else if (s_flag && e_flag) {
		/*
		 * Don't use the strerror() message for EPERM, "Not Owner"
		 * which is misleading.
		 */
		errc = psecflags(P_PID, P_MYID, which, &act);
		switch (errc) {
		case 0:
			break;
		case EPERM:
			errx(1, gettext("failed setting "
			    "security-flags: Permission denied"));
			break;
		default:
			err(1, gettext("failed setting security-flags"));
		}

		(void) execvp(argv[0], &argv[0]);
		err(1, "%s", argv[0]);
	} else if (s_flag) {
		int i;
		id_t id;

		if (idtypename != NULL)
			if (str2idtype(idtypename, &idtype) == -1)
				errx(1, gettext("No such id type: '%s'"),
				    idtypename);

		for (i = 0; i < argc; i++) {
			if ((id = getid(idtype, argv[i])) == (id_t)-1) {
				errx(1, gettext("invalid or non-existent "
				    "identifier: '%s'"), argv[i]);
			}

			/*
			 * Don't use the strerror() message for EPERM, "Not
			 * Owner" which is misleading.
			 */
			if (psecflags(idtype, id, which, &act) != 0) {
				switch (errno) {
				case EPERM:
					errx(1, gettext("failed setting "
					    "security-flags: "
					    "Permission denied"));
					break;
				default:
					err(1, gettext("failed setting "
					    "security-flags"));
				}
			}
		}

		return (0);
	}

	/* Display the flags for the given pids */
	while (argc-- > 0) {
		struct ps_prochandle *Pr;
		const char *arg;
		psinfo_t psinfo;
		prsecflags_t *psf;
		int gcode;

		if ((Pr = proc_arg_grab(arg = *argv++, PR_ARG_ANY,
		    pgrab_flags, &gcode)) == NULL) {
			warnx(gettext("cannot examine %s: %s"),
			    arg, Pgrab_error(gcode));
			ret = 1;
			continue;
		}

		(void) memcpy(&psinfo, Ppsinfo(Pr), sizeof (psinfo_t));
		proc_unctrl_psinfo(&psinfo);

		if (Pstate(Pr) == PS_DEAD) {
			(void) printf(gettext("core '%s' of %d:\t%.70s\n"),
			    arg, (int)psinfo.pr_pid, psinfo.pr_psargs);
		} else {
			(void) printf("%d:\t%.70s\n",
			    (int)psinfo.pr_pid, psinfo.pr_psargs);
		}

		if (Psecflags(Pr, &psf) != 0)
			err(1, gettext("cannot read secflags of %s"), arg);

		print_flags("E", psf->pr_effective);
		print_flags("I", psf->pr_inherit);
		print_flags("L", psf->pr_lower);
		print_flags("U", psf->pr_upper);

		Psecflags_free(psf);
		Prelease(Pr, 0);
	}

	return (ret);
}