Example #1
0
static char *
prwhat(int why, int what)
{
	static char buf[32];
	char *str;

	switch (why) {
	case PR_SIGNALLED:
	case PR_JOBCONTROL:
		str = proc_signame(what, buf, sizeof (buf));
		break;
	case PR_SYSENTRY:
	case PR_SYSEXIT:
		str = proc_sysname(what, buf, sizeof (buf));
		break;
	case PR_FAULTED:
		str = proc_fltname(what, buf, sizeof (buf));
		break;
	default:
		(void) sprintf(str = buf, "%d", what);
		break;
	}

	return (str);
}
Example #2
0
/*ARGSUSED*/
static void
prochandler(struct ps_prochandle *P, const char *msg, void *arg)
{
#if !defined(__APPLE__)
	const psinfo_t *prp = Ppsinfo(P);
	int pid = Pstatus(P)->pr_pid;
	char name[SIG2STR_MAX];
#else
#define SIG2STR_MAX 32 /* Not referenced so long as prp just below is NULL. */
#define proc_signame(x,y,z) "Unknown" /* Not referenced so long as prp just below is NULL. */
	typedef struct psinfo { int pr_wstat; } psinfo_t;
	const psinfo_t *prp = NULL;
	int pid = Pstatus(P)->pr_pid;
#endif /* __APPLE__ */

	if (msg != NULL) {
		notice("pid %d: %s\n", pid, msg);
		return;
	}

	switch (Pstate(P)) {
	case PS_UNDEAD:
		/*
		 * Ideally we would like to always report pr_wstat here, but it
		 * isn't possible given current /proc semantics.  If we grabbed
		 * the process, Ppsinfo() will either fail or return a zeroed
		 * psinfo_t depending on how far the parent is in reaping it.
		 * When /proc provides a stable pr_wstat in the status file,
		 * this code can be improved by examining this new pr_wstat.
		 */
		if (prp != NULL && WIFSIGNALED(prp->pr_wstat)) {
			notice("pid %d terminated by %s\n", pid,
			    proc_signame(WTERMSIG(prp->pr_wstat),
			    name, sizeof (name)));
		} else if (prp != NULL && WEXITSTATUS(prp->pr_wstat) != 0) {
			notice("pid %d exited with status %d\n",
			    pid, WEXITSTATUS(prp->pr_wstat));
		} else {
			notice("pid %d has exited\n", pid);
		}
		g_exited = 1;
		break;

	case PS_LOST:
#if !defined(__APPLE__)
		notice("pid %d exec'd a set-id or unobservable program\n", pid);
#else
		notice("pid %d has exited\n", pid);
#endif
		g_exited = 1;
		break;
	}
}
Example #3
0
/*ARGSUSED*/
static void
prochandler(struct ps_prochandle *P, const char *msg, void *arg)
{
#if defined(sun)
	const psinfo_t *prp = Ppsinfo(P);
	int pid = Pstatus(P)->pr_pid;
	char name[SIG2STR_MAX];
#else
	int wstatus = proc_getwstat(P);
	int pid = proc_getpid(P);
#endif

	if (msg != NULL) {
		notice("pid %d: %s\n", pid, msg);
		return;
	}

#if defined(sun)
	switch (Pstate(P)) {
#else
	switch (proc_state(P)) {
#endif
	case PS_UNDEAD:
#if defined(sun)
		/*
		 * Ideally we would like to always report pr_wstat here, but it
		 * isn't possible given current /proc semantics.  If we grabbed
		 * the process, Ppsinfo() will either fail or return a zeroed
		 * psinfo_t depending on how far the parent is in reaping it.
		 * When /proc provides a stable pr_wstat in the status file,
		 * this code can be improved by examining this new pr_wstat.
		 */
		if (prp != NULL && WIFSIGNALED(prp->pr_wstat)) {
			notice("pid %d terminated by %s\n", pid,
			    proc_signame(WTERMSIG(prp->pr_wstat),
			    name, sizeof (name)));
#else
		if (WIFSIGNALED(wstatus)) {
			notice("pid %d terminated by %d\n", pid,
			    WTERMSIG(wstatus));
#endif
#if defined(sun)
		} else if (prp != NULL && WEXITSTATUS(prp->pr_wstat) != 0) {
			notice("pid %d exited with status %d\n",
			    pid, WEXITSTATUS(prp->pr_wstat));
#else
		} else if (WEXITSTATUS(wstatus) != 0) {
			notice("pid %d exited with status %d\n",
			    pid, WEXITSTATUS(wstatus));
#endif
		} else {
			notice("pid %d has exited\n", pid);
		}
		g_pslive--;
		break;

	case PS_LOST:
		notice("pid %d exec'd a set-id or unobservable program\n", pid);
		g_pslive--;
		break;
	}
}

/*ARGSUSED*/
static int
errhandler(const dtrace_errdata_t *data, void *arg)
{
	error(data->dteda_msg);
	return (DTRACE_HANDLE_OK);
}

/*ARGSUSED*/
static int
drophandler(const dtrace_dropdata_t *data, void *arg)
{
	error(data->dtdda_msg);
	return (DTRACE_HANDLE_OK);
}
Example #4
0
static int
lwplook(look_arg_t *arg, const lwpstatus_t *psp, const lwpsinfo_t *pip)
{
	int flags;
	uint32_t sighold, sighold1, sighold2;
	uint32_t sigpend, sigpend1, sigpend2;
	int cursig;
	char buf[32];

	if (!proc_lwp_in_set(arg->lwps, pip->pr_lwpid))
		return (0);

	arg->count++;

	if (psp == NULL)
		return (lwplook_zombie(pip));

	/*
	 * PR_PCINVAL is just noise if the lwp is not stopped.
	 * Don't bother reporting it unless the lwp is stopped.
	 */
	flags = psp->pr_flags & LWPFLAGS;
	if (!(flags & PR_STOPPED))
		flags &= ~PR_PCINVAL;

	(void) printf(" /%d:\tflags = %s", (int)psp->pr_lwpid, prflags(flags));
	if ((flags & PR_ASLEEP) || (psp->pr_syscall &&
	    !(arg->pflags & PR_ISSYS))) {
		if (flags & PR_ASLEEP) {
			if ((flags & ~PR_ASLEEP) != 0)
				(void) printf("|");
			(void) printf("ASLEEP");
		}
		if (psp->pr_syscall && !(arg->pflags & PR_ISSYS)) {
			uint_t i;

			(void) printf("  %s(",
			    proc_sysname(psp->pr_syscall, buf, sizeof (buf)));
			for (i = 0; i < psp->pr_nsysarg; i++) {
				if (i != 0)
					(void) printf(",");
				(void) printf("0x%lx", psp->pr_sysarg[i]);
			}
			(void) printf(")");
		}
	}
	(void) printf("\n");

	if (flags & PR_STOPPED) {
		(void) printf("\twhy = %s", prwhy(psp->pr_why));
		if (psp->pr_why != PR_REQUESTED &&
		    psp->pr_why != PR_SUSPENDED)
			(void) printf("  what = %s",
			    prwhat(psp->pr_why, psp->pr_what));
		(void) printf("\n");
	}

#if (MAXSIG > 2 * 32) && (MAXSIG <= 3 * 32)	/* assumption */
	sighold  = *((uint32_t *)&psp->pr_lwphold);
	sighold1 = *((uint32_t *)&psp->pr_lwphold + 1);
	sighold2 = *((uint32_t *)&psp->pr_lwphold + 2);
	sigpend  = *((uint32_t *)&psp->pr_lwppend);
	sigpend1 = *((uint32_t *)&psp->pr_lwppend + 1);
	sigpend2 = *((uint32_t *)&psp->pr_lwppend + 2);
#else
#error "fix me: MAXSIG out of bounds"
#endif
	cursig   = psp->pr_cursig;

	if (sighold | sighold1 | sighold2)
		(void) printf("\tsigmask = 0x%.8x,0x%.8x,0x%.8x\n",
		    sighold, sighold1, sighold2);
	if (sigpend | sigpend1 | sigpend2)
		(void) printf("\tlwppend = 0x%.8x,0x%.8x,0x%.8x\n",
		    sigpend, sigpend1, sigpend2);
	if (cursig)
		(void) printf("\tcursig = %s\n",
		    proc_signame(cursig, buf, sizeof (buf)));

	if (rflag) {
		if (Pstate(Pr) == PS_DEAD || (arg->pflags & PR_STOPPED)) {
#if defined(__sparc) && defined(_ILP32)
			/*
			 * If we're SPARC/32-bit, see if we can get extra
			 * register state for this lwp.  If it's a v8plus
			 * program, print the 64-bit register values.
			 */
			prxregset_t prx;

			if (Plwp_getxregs(Pr, psp->pr_lwpid, &prx) == 0 &&
			    prx.pr_type == XR_TYPE_V8P)
				dumpregs_v8p(psp->pr_reg, &prx, is64);
			else
#endif	/* __sparc && _ILP32 */
				dumpregs(psp->pr_reg, is64);
		} else
			(void) printf("\tNot stopped, can't show registers\n");
	}

	return (0);
}
Example #5
0
int
main(int argc, char **argv)
{
	int opt, exit;
	pid_t pid;
	struct siginfo info;
	int status;
	int gret;
	struct ps_prochandle *Pr;

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

	while ((opt = getopt(argc, argv, "Fhmp:")) != EOF) {
		switch (opt) {
		case 'F':		/* force grabbing (no O_EXCL) */
			Fflag = PGRAB_FORCE;
			break;
		case 'm':		/* microstate accounting */
			mflag = 1;
			break;
		case 'p':
			pflag = 1;
			pidarg = optarg;
			break;
		default:
			errflg = 1;
			break;
		}
	}

	argc -= optind;
	argv += optind;

	if (((pidarg != NULL) ^ (argc < 1)) || errflg) {
		(void) fprintf(stderr,
		    "usage:\t%s [-mh] [-p pidlist | command [ args ... ]]\n",
		    command);
		(void) fprintf(stderr,
		    "  (time a command using microstate accounting)\n");
		return (1);
	}

	if (pflag) {
		char *pp;

		exit = 0;
		(void) signal(SIGINT, SIG_IGN);
		(void) signal(SIGQUIT, SIG_IGN);

		pp = strtok(pidarg, ", ");
		if (pp == NULL) {
			(void) fprintf(stderr, "%s: invalid argument for -p\n",
			    command);
			return (1);
		}
		exit = ptime_pid(pp);
		while ((pp = strtok(NULL, ", ")) != NULL) {
			exit |= ptime_pid(pp);
		}
		return (exit);
	}


	if ((Pr = Pcreate(argv[0], &argv[0], &gret, NULL, 0)) == NULL) {
		(void) fprintf(stderr, "%s: failed to exec %s: %s\n",
		    command, argv[0], Pcreate_error(gret));
		return (1);
	}
	if (Psetrun(Pr, 0, 0) == -1) {
		(void) fprintf(stderr, "%s: failed to set running %s: "
		    "%s\n", command, argv[0], strerror(errno));
		return (1);
	}

	pid = Pstatus(Pr)->pr_pid;

	(void) sprintf(procname, "%d", (int)pid);	/* for perr() */
	(void) signal(SIGINT, SIG_IGN);
	(void) signal(SIGQUIT, SIG_IGN);

	(void) waitid(P_PID, pid, &info, WEXITED | WNOWAIT);

	(void) look(pid);

	(void) waitpid(pid, &status, 0);

	if (WIFEXITED(status))
		return (WEXITSTATUS(status));

	if (WIFSIGNALED(status)) {
		int sig = WTERMSIG(status);
		char name[SIG2STR_MAX];

		(void) fprintf(stderr, "%s: command terminated "
		    "abnormally by %s\n", command,
		    proc_signame(sig, name, sizeof (name)));
	}

	return (status | WCOREFLG); /* see time(1) */
}