Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather only scalar values and structures that are already part of the kernel/user interface, specifically rusage and rtprio. It no longer contains proc, session, pcred, ucred, procsig, vmspace, pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If any of these changed in size, ps, w, fstat, gcore, systat, and top would all stop working. The new structure has over 200 bytes of unassigned space for future values to be added, yet is nearly 100 bytes smaller per entry than the structure that it replaced.
This commit is contained in:
parent
522b7bcdf6
commit
1f7d250182
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=69896
@ -49,10 +49,10 @@ __BEGIN_DECLS
|
||||
void command __P((KINFO *, VARENT *));
|
||||
void cputime __P((KINFO *, VARENT *));
|
||||
int donlist __P((void));
|
||||
void evar __P((KINFO *, VARENT *));
|
||||
char *fmt_argv __P((char **, char *, int));
|
||||
double getpcpu __P((KINFO *));
|
||||
double getpmem __P((KINFO *));
|
||||
void kvar __P((KINFO *, VARENT *));
|
||||
void logname __P((KINFO *, VARENT *));
|
||||
void longtname __P((KINFO *, VARENT *));
|
||||
void lstarted __P((KINFO *, VARENT *));
|
||||
@ -67,7 +67,6 @@ void pmem __P((KINFO *, VARENT *));
|
||||
void pri __P((KINFO *, VARENT *));
|
||||
void rtprior __P((KINFO *, VARENT *));
|
||||
void printheader __P((void));
|
||||
void pvar __P((KINFO *, VARENT *));
|
||||
void rssize __P((KINFO *, VARENT *));
|
||||
void runame __P((KINFO *, VARENT *));
|
||||
int s_runame __P((KINFO *));
|
||||
@ -81,7 +80,6 @@ void tsize __P((KINFO *, VARENT *));
|
||||
void ucomm __P((KINFO *, VARENT *));
|
||||
void uname __P((KINFO *, VARENT *));
|
||||
int s_uname __P((KINFO *));
|
||||
void uvar __P((KINFO *, VARENT *));
|
||||
void vsize __P((KINFO *, VARENT *));
|
||||
void wchan __P((KINFO *, VARENT *));
|
||||
__END_DECLS
|
||||
|
@ -71,8 +71,7 @@ int utime(), stime(), ixrss(), idrss(), isrss();
|
||||
#endif
|
||||
|
||||
/* Compute offset in common structures. */
|
||||
#define POFF(x) offsetof(struct proc, x)
|
||||
#define EOFF(x) offsetof(struct eproc, x)
|
||||
#define KOFF(x) offsetof(struct kinfo_proc, x)
|
||||
#define UOFF(x) offsetof(struct usave, x)
|
||||
#define ROFF(x) offsetof(struct rusage, x)
|
||||
|
||||
@ -86,24 +85,22 @@ VAR var[] = {
|
||||
{"%cpu", "%CPU", NULL, 0, pcpu, NULL, 4},
|
||||
{"%mem", "%MEM", NULL, 0, pmem, NULL, 4},
|
||||
{"acflag", "ACFLG",
|
||||
NULL, 0, pvar, NULL, 3, POFF(p_acflag), USHORT, "x"},
|
||||
NULL, 0, kvar, NULL, 3, KOFF(ki_acflag), USHORT, "x"},
|
||||
{"acflg", "", "acflag"},
|
||||
{"blocked", "", "sigmask"},
|
||||
{"caught", "", "sigcatch"},
|
||||
{"command", "COMMAND", NULL, COMM|LJUST|USER, command, NULL, 16},
|
||||
{"cpu", "CPU", NULL, 0, pvar, NULL, 3, POFF(p_estcpu), UINT, "d"},
|
||||
{"cpu", "CPU", NULL, 0, kvar, NULL, 3, KOFF(ki_estcpu), UINT, "d"},
|
||||
{"cputime", "", "time"},
|
||||
{"f", "F", NULL, 0, pvar, NULL, 7, POFF(p_flag), INT, "x"},
|
||||
{"f", "F", NULL, 0, kvar, NULL, 7, KOFF(ki_flag), INT, "x"},
|
||||
{"flags", "", "f"},
|
||||
{"ignored", "", "sigignore"},
|
||||
{"inblk", "INBLK",
|
||||
NULL, USER, rvar, NULL, 4, ROFF(ru_inblock), LONG, "ld"},
|
||||
{"inblock", "", "inblk"},
|
||||
{"jobc", "JOBC", NULL, 0, evar, NULL, 4, EOFF(e_jobc), SHORT, "d"},
|
||||
{"jobc", "JOBC", NULL, 0, kvar, NULL, 4, KOFF(ki_jobc), SHORT, "d"},
|
||||
{"ktrace", "KTRACE",
|
||||
NULL, 0, pvar, NULL, 8, POFF(p_traceflag), INT, "x"},
|
||||
{"ktracep", "KTRACEP",
|
||||
NULL, 0, pvar, NULL, 8, POFF(p_tracep), LONG, "lx"},
|
||||
NULL, 0, kvar, NULL, 8, KOFF(ki_traceflag), INT, "x"},
|
||||
{"lim", "LIM", NULL, 0, maxrss, NULL, 5},
|
||||
{"login", "LOGIN", NULL, LJUST, logname, NULL, MAXLOGNAME-1},
|
||||
{"logname", "", "login"},
|
||||
@ -118,7 +115,7 @@ VAR var[] = {
|
||||
{"msgsnd", "MSGSND",
|
||||
NULL, USER, rvar, NULL, 4, ROFF(ru_msgsnd), LONG, "ld"},
|
||||
{"ni", "", "nice"},
|
||||
{"nice", "NI", NULL, 0, pvar, NULL, 2, POFF(p_nice), CHAR, "d"},
|
||||
{"nice", "NI", NULL, 0, kvar, NULL, 2, KOFF(ki_nice), CHAR, "d"},
|
||||
{"nivcsw", "NIVCSW",
|
||||
NULL, USER, rvar, NULL, 5, ROFF(ru_nivcsw), LONG, "ld"},
|
||||
{"nsignals", "", "nsigs"},
|
||||
@ -128,68 +125,60 @@ VAR var[] = {
|
||||
NULL, USER, rvar, NULL, 4, ROFF(ru_nswap), LONG, "ld"},
|
||||
{"nvcsw", "NVCSW",
|
||||
NULL, USER, rvar, NULL, 5, ROFF(ru_nvcsw), LONG, "ld"},
|
||||
{"nwchan", "WCHAN", NULL, 0, pvar, NULL, 6, POFF(p_wchan), KPTR, "lx"},
|
||||
{"nwchan", "WCHAN", NULL, 0, kvar, NULL, 6, KOFF(ki_wchan), KPTR, "lx"},
|
||||
{"oublk", "OUBLK",
|
||||
NULL, USER, rvar, NULL, 4, ROFF(ru_oublock), LONG, "ld"},
|
||||
{"oublock", "", "oublk"},
|
||||
{"p_ru", "P_RU", NULL, 0, pvar, NULL, 6, POFF(p_ru), KPTR, "lx"},
|
||||
{"paddr", "PADDR", NULL, 0, evar, NULL, 6, EOFF(e_paddr), KPTR, "lx"},
|
||||
{"paddr", "PADDR", NULL, 0, kvar, NULL, 6, KOFF(ki_paddr), KPTR, "lx"},
|
||||
{"pagein", "PAGEIN", NULL, USER, pagein, NULL, 6},
|
||||
{"pcpu", "", "%cpu"},
|
||||
{"pending", "", "sig"},
|
||||
{"pgid", "PGID",
|
||||
NULL, 0, evar, NULL, PIDLEN, EOFF(e_pgid), UINT, PIDFMT},
|
||||
{"pid", "PID", NULL, 0, pvar, NULL, PIDLEN, POFF(p_pid), UINT, PIDFMT},
|
||||
NULL, 0, kvar, NULL, PIDLEN, KOFF(ki_pgid), UINT, PIDFMT},
|
||||
{"pid", "PID", NULL, 0, kvar, NULL, PIDLEN, KOFF(ki_pid), UINT, PIDFMT},
|
||||
{"pmem", "", "%mem"},
|
||||
{"ppid", "PPID",
|
||||
NULL, 0, evar, NULL, PIDLEN, EOFF(e_ppid), UINT, PIDFMT},
|
||||
NULL, 0, kvar, NULL, PIDLEN, KOFF(ki_ppid), UINT, PIDFMT},
|
||||
{"pri", "PRI", NULL, 0, pri, NULL, 3},
|
||||
{"re", "RE", NULL, 0, pvar, NULL, 3, POFF(p_swtime), UINT, "d"},
|
||||
{"rgid", "RGID", NULL, 0, evar, NULL, UIDLEN, EOFF(e_pcred.p_rgid),
|
||||
{"re", "RE", NULL, 0, kvar, NULL, 3, KOFF(ki_swtime), UINT, "d"},
|
||||
{"rgid", "RGID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_rgid),
|
||||
UINT, UIDFMT},
|
||||
{"rlink", "RLINK",
|
||||
NULL, 0, pvar, NULL, 8, POFF(p_procq.tqe_prev), KPTR, "lx"},
|
||||
{"rss", "RSS", NULL, 0, p_rssize, NULL, 4},
|
||||
{"rssize", "", "rsz"},
|
||||
{"rsz", "RSZ", NULL, 0, rssize, NULL, 4},
|
||||
{"rtprio", "RTPRIO", NULL, 0, rtprior, NULL, 7, POFF(p_rtprio)},
|
||||
{"ruid", "RUID", NULL, 0, evar, NULL, UIDLEN, EOFF(e_pcred.p_ruid),
|
||||
{"rtprio", "RTPRIO", NULL, 0, rtprior, NULL, 7, KOFF(ki_rtprio)},
|
||||
{"ruid", "RUID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_ruid),
|
||||
UINT, UIDFMT},
|
||||
{"ruser", "RUSER", NULL, LJUST|DSIZ, runame, s_runame, USERLEN},
|
||||
{"sess", "SESS", NULL, 0, evar, NULL, 6, EOFF(e_sess), KPTR, "lx"},
|
||||
{"sig", "PENDING", NULL, 0, pvar, NULL, 8, POFF(p_siglist), INT, "x"},
|
||||
{"sig", "PENDING", NULL, 0, kvar, NULL, 8, KOFF(ki_siglist), INT, "x"},
|
||||
{"sigcatch", "CAUGHT",
|
||||
NULL, 0, evar, NULL, 8, EOFF(e_procsig.ps_sigcatch), UINT, "x"},
|
||||
NULL, 0, kvar, NULL, 8, KOFF(ki_sigcatch), UINT, "x"},
|
||||
{"sigignore", "IGNORED",
|
||||
NULL, 0, evar, NULL, 8, EOFF(e_procsig.ps_sigignore), UINT, "x"},
|
||||
NULL, 0, kvar, NULL, 8, KOFF(ki_sigignore), UINT, "x"},
|
||||
{"sigmask", "BLOCKED",
|
||||
NULL, 0, pvar, NULL, 8, POFF(p_sigmask), UINT, "x"},
|
||||
{"sl", "SL", NULL, 0, pvar, NULL, 3, POFF(p_slptime), UINT, "d"},
|
||||
NULL, 0, kvar, NULL, 8, KOFF(ki_sigmask), UINT, "x"},
|
||||
{"sl", "SL", NULL, 0, kvar, NULL, 3, KOFF(ki_slptime), UINT, "d"},
|
||||
{"start", "STARTED", NULL, LJUST|USER, started, NULL, 7},
|
||||
{"stat", "", "state"},
|
||||
{"state", "STAT", NULL, 0, state, NULL, 4},
|
||||
{"svgid", "SVGID", NULL, 0,
|
||||
evar, NULL, UIDLEN, EOFF(e_pcred.p_svgid), UINT, UIDFMT},
|
||||
kvar, NULL, UIDLEN, KOFF(ki_svgid), UINT, UIDFMT},
|
||||
{"svuid", "SVUID", NULL, 0,
|
||||
evar, NULL, UIDLEN, EOFF(e_pcred.p_svuid), UINT, UIDFMT},
|
||||
kvar, NULL, UIDLEN, KOFF(ki_svuid), UINT, UIDFMT},
|
||||
{"tdev", "TDEV", NULL, 0, tdev, NULL, 4},
|
||||
{"time", "TIME", NULL, USER, cputime, NULL, 9},
|
||||
{"tpgid", "TPGID",
|
||||
NULL, 0, evar, NULL, 4, EOFF(e_tpgid), UINT, PIDFMT},
|
||||
{"tsess", "TSESS", NULL, 0, evar, NULL, 6, EOFF(e_tsess), KPTR, "lx"},
|
||||
NULL, 0, kvar, NULL, 4, KOFF(ki_tpgid), UINT, PIDFMT},
|
||||
{"tsiz", "TSIZ", NULL, 0, tsize, NULL, 4},
|
||||
{"tt", "TT ", NULL, 0, tname, NULL, 4},
|
||||
{"tty", "TTY", NULL, LJUST, longtname, NULL, 8},
|
||||
{"ucomm", "UCOMM", NULL, LJUST, ucomm, NULL, MAXCOMLEN},
|
||||
{"uid", "UID", NULL, 0, evar, NULL, UIDLEN, EOFF(e_ucred.cr_uid),
|
||||
{"uid", "UID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_uid),
|
||||
UINT, UIDFMT},
|
||||
{"upr", "UPR", NULL, 0, pvar, NULL, 3, POFF(p_usrpri), CHAR, "d"},
|
||||
{"upr", "UPR", NULL, 0, kvar, NULL, 3, KOFF(ki_usrpri), CHAR, "d"},
|
||||
{"user", "USER", NULL, LJUST|DSIZ, uname, s_uname, USERLEN},
|
||||
{"usrpri", "", "upr"},
|
||||
{"vsize", "", "vsz"},
|
||||
{"vsz", "VSZ", NULL, 0, vsize, NULL, 5},
|
||||
{"wchan", "WCHAN", NULL, LJUST, wchan, NULL, 6},
|
||||
{"xstat", "XSTAT", NULL, 0, pvar, NULL, 4, POFF(p_xstat), USHORT, "x"},
|
||||
{"xstat", "XSTAT", NULL, 0, kvar, NULL, 4, KOFF(ki_xstat), USHORT, "x"},
|
||||
{""},
|
||||
};
|
||||
|
||||
|
147
bin/ps/print.c
147
bin/ps/print.c
@ -96,9 +96,9 @@ command(k, ve)
|
||||
|
||||
if (cflag) {
|
||||
if (ve->next == NULL) /* last field, don't pad */
|
||||
(void)printf("%s", KI_PROC(k)->p_comm);
|
||||
(void)printf("%s", k->ki_p->ki_comm);
|
||||
else
|
||||
(void)printf("%-*s", v->width, KI_PROC(k)->p_comm);
|
||||
(void)printf("%-*s", v->width, k->ki_p->ki_comm);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ ucomm(k, ve)
|
||||
VAR *v;
|
||||
|
||||
v = ve->var;
|
||||
(void)printf("%-*s", v->width, KI_PROC(k)->p_comm);
|
||||
(void)printf("%-*s", v->width, k->ki_p->ki_comm);
|
||||
}
|
||||
|
||||
void
|
||||
@ -159,7 +159,7 @@ logname(k, ve)
|
||||
char *s;
|
||||
|
||||
v = ve->var;
|
||||
(void)printf("%-*s", v->width, (s = KI_EPROC(k)->e_login, *s) ? s : "-");
|
||||
(void)printf("%-*s", v->width, (s = k->ki_p->ki_login, *s) ? s : "-");
|
||||
}
|
||||
|
||||
void
|
||||
@ -167,18 +167,16 @@ state(k, ve)
|
||||
KINFO *k;
|
||||
VARENT *ve;
|
||||
{
|
||||
struct proc *p;
|
||||
int flag;
|
||||
char *cp;
|
||||
VAR *v;
|
||||
char buf[16];
|
||||
|
||||
v = ve->var;
|
||||
p = KI_PROC(k);
|
||||
flag = p->p_flag;
|
||||
flag = k->ki_p->ki_flag;
|
||||
cp = buf;
|
||||
|
||||
switch (p->p_stat) {
|
||||
switch (k->ki_p->ki_stat) {
|
||||
|
||||
case SSTOP:
|
||||
*cp = 'T';
|
||||
@ -186,7 +184,7 @@ state(k, ve)
|
||||
|
||||
case SSLEEP:
|
||||
if (flag & P_SINTR) /* interruptable (long) */
|
||||
*cp = p->p_slptime >= MAXSLP ? 'I' : 'S';
|
||||
*cp = k->ki_p->ki_slptime >= MAXSLP ? 'I' : 'S';
|
||||
else
|
||||
*cp = 'D';
|
||||
break;
|
||||
@ -214,21 +212,21 @@ state(k, ve)
|
||||
cp++;
|
||||
if (!(flag & P_INMEM))
|
||||
*cp++ = 'W';
|
||||
if (p->p_nice < NZERO)
|
||||
if (k->ki_p->ki_nice < NZERO)
|
||||
*cp++ = '<';
|
||||
else if (p->p_nice > NZERO)
|
||||
else if (k->ki_p->ki_nice > NZERO)
|
||||
*cp++ = 'N';
|
||||
if (flag & P_TRACED)
|
||||
*cp++ = 'X';
|
||||
if (flag & P_WEXIT && p->p_stat != SZOMB)
|
||||
if (flag & P_WEXIT && k->ki_p->ki_stat != SZOMB)
|
||||
*cp++ = 'E';
|
||||
if (flag & P_PPWAIT)
|
||||
*cp++ = 'V';
|
||||
if ((flag & P_SYSTEM) || p->p_lock > 0)
|
||||
if ((flag & P_SYSTEM) || k->ki_p->ki_lock > 0)
|
||||
*cp++ = 'L';
|
||||
if (KI_EPROC(k)->e_flag & EPROC_SLEADER)
|
||||
if (k->ki_p->ki_kiflag & KI_SLEADER)
|
||||
*cp++ = 's';
|
||||
if ((flag & P_CONTROLT) && KI_EPROC(k)->e_pgid == KI_EPROC(k)->e_tpgid)
|
||||
if ((flag & P_CONTROLT) && k->ki_p->ki_pgid == k->ki_p->ki_tpgid)
|
||||
*cp++ = '+';
|
||||
if (flag & P_JAILED)
|
||||
*cp++ = 'J';
|
||||
@ -244,7 +242,7 @@ pri(k, ve)
|
||||
VAR *v;
|
||||
|
||||
v = ve->var;
|
||||
(void)printf("%*d", v->width, KI_PROC(k)->p_priority - PZERO);
|
||||
(void)printf("%*d", v->width, k->ki_p->ki_priority - PZERO);
|
||||
}
|
||||
|
||||
void
|
||||
@ -256,14 +254,14 @@ uname(k, ve)
|
||||
|
||||
v = ve->var;
|
||||
(void)printf("%-*s",
|
||||
(int)v->width, user_from_uid(KI_EPROC(k)->e_ucred.cr_uid, 0));
|
||||
(int)v->width, user_from_uid(k->ki_p->ki_uid, 0));
|
||||
}
|
||||
|
||||
int
|
||||
s_uname(k)
|
||||
KINFO *k;
|
||||
{
|
||||
return (strlen(user_from_uid(KI_EPROC(k)->e_ucred.cr_uid, 0)));
|
||||
return (strlen(user_from_uid(k->ki_p->ki_uid, 0)));
|
||||
}
|
||||
|
||||
void
|
||||
@ -275,14 +273,14 @@ runame(k, ve)
|
||||
|
||||
v = ve->var;
|
||||
(void)printf("%-*s",
|
||||
(int)v->width, user_from_uid(KI_EPROC(k)->e_pcred.p_ruid, 0));
|
||||
(int)v->width, user_from_uid(k->ki_p->ki_ruid, 0));
|
||||
}
|
||||
|
||||
int
|
||||
s_runame(k)
|
||||
KINFO *k;
|
||||
{
|
||||
return (strlen(user_from_uid(KI_EPROC(k)->e_pcred.p_ruid, 0)));
|
||||
return (strlen(user_from_uid(k->ki_p->ki_ruid, 0)));
|
||||
}
|
||||
|
||||
void
|
||||
@ -295,7 +293,7 @@ tdev(k, ve)
|
||||
char buff[16];
|
||||
|
||||
v = ve->var;
|
||||
dev = KI_EPROC(k)->e_tdev;
|
||||
dev = k->ki_p->ki_tdev;
|
||||
if (dev == NODEV)
|
||||
(void)printf("%*s", v->width, "??");
|
||||
else {
|
||||
@ -315,7 +313,7 @@ tname(k, ve)
|
||||
char *ttname;
|
||||
|
||||
v = ve->var;
|
||||
dev = KI_EPROC(k)->e_tdev;
|
||||
dev = k->ki_p->ki_tdev;
|
||||
if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
|
||||
(void)printf("%*s ", v->width-1, "??");
|
||||
else {
|
||||
@ -323,7 +321,7 @@ tname(k, ve)
|
||||
strncmp(ttname, "cua", 3) == 0)
|
||||
ttname += 3;
|
||||
(void)printf("%*.*s%c", v->width-1, v->width-1, ttname,
|
||||
KI_EPROC(k)->e_flag & EPROC_CTTY ? ' ' : '-');
|
||||
k->ki_p->ki_kiflag & KI_CTTY ? ' ' : '-');
|
||||
}
|
||||
}
|
||||
|
||||
@ -337,7 +335,7 @@ longtname(k, ve)
|
||||
char *ttname;
|
||||
|
||||
v = ve->var;
|
||||
dev = KI_EPROC(k)->e_tdev;
|
||||
dev = k->ki_p->ki_tdev;
|
||||
if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
|
||||
(void)printf("%-*s", v->width, "??");
|
||||
else
|
||||
@ -356,18 +354,18 @@ started(k, ve)
|
||||
char buf[100];
|
||||
|
||||
v = ve->var;
|
||||
if (!k->ki_u.u_valid) {
|
||||
if (!k->ki_valid) {
|
||||
(void)printf("%-*s", v->width, "-");
|
||||
return;
|
||||
}
|
||||
|
||||
then = k->ki_u.u_start.tv_sec;
|
||||
then = k->ki_p->ki_start.tv_sec;
|
||||
tp = localtime(&then);
|
||||
if (!now)
|
||||
(void)time(&now);
|
||||
if (now - k->ki_u.u_start.tv_sec < 24 * 3600) {
|
||||
if (now - k->ki_p->ki_start.tv_sec < 24 * 3600) {
|
||||
(void)strftime(buf, sizeof(buf) - 1, "%l:%M%p", tp);
|
||||
} else if (now - k->ki_u.u_start.tv_sec < 7 * 86400) {
|
||||
} else if (now - k->ki_p->ki_start.tv_sec < 7 * 86400) {
|
||||
(void)strftime(buf, sizeof(buf) - 1, "%a%I%p", tp);
|
||||
} else
|
||||
(void)strftime(buf, sizeof(buf) - 1, "%e%b%y", tp);
|
||||
@ -384,11 +382,11 @@ lstarted(k, ve)
|
||||
char buf[100];
|
||||
|
||||
v = ve->var;
|
||||
if (!k->ki_u.u_valid) {
|
||||
if (!k->ki_valid) {
|
||||
(void)printf("%-*s", v->width, "-");
|
||||
return;
|
||||
}
|
||||
then = k->ki_u.u_start.tv_sec;
|
||||
then = k->ki_p->ki_start.tv_sec;
|
||||
(void)strftime(buf, sizeof(buf) -1, "%c", localtime(&then));
|
||||
(void)printf("%-*s", v->width, buf);
|
||||
}
|
||||
@ -401,10 +399,10 @@ mtxname(k, ve)
|
||||
VAR *v;
|
||||
|
||||
v = ve->var;
|
||||
if (KI_PROC(k)->p_blocked) {
|
||||
if (KI_PROC(k)->p_mtxname)
|
||||
if (k->ki_p->ki_kiflag & KI_MTXBLOCK) {
|
||||
if (k->ki_p->ki_mtxname[0] != 0)
|
||||
(void)printf("%-*.*s", v->width, v->width,
|
||||
KI_EPROC(k)->e_mtxname);
|
||||
k->ki_p->ki_mtxname);
|
||||
else
|
||||
(void)printf("%-*s", v->width, "???");
|
||||
} else
|
||||
@ -419,13 +417,13 @@ wchan(k, ve)
|
||||
VAR *v;
|
||||
|
||||
v = ve->var;
|
||||
if (KI_PROC(k)->p_wchan) {
|
||||
if (KI_PROC(k)->p_wmesg)
|
||||
if (k->ki_p->ki_wchan) {
|
||||
if (k->ki_p->ki_wmesg[0] != 0)
|
||||
(void)printf("%-*.*s", v->width, v->width,
|
||||
KI_EPROC(k)->e_wmesg);
|
||||
k->ki_p->ki_wmesg);
|
||||
else
|
||||
(void)printf("%-*lx", v->width,
|
||||
(long)KI_PROC(k)->p_wchan &~ KERNBASE);
|
||||
(long)k->ki_p->ki_wchan &~ KERNBASE);
|
||||
} else
|
||||
(void)printf("%-*s", v->width, "-");
|
||||
}
|
||||
@ -443,7 +441,7 @@ vsize(k, ve)
|
||||
|
||||
v = ve->var;
|
||||
(void)printf("%*d", v->width,
|
||||
(KI_EPROC(k)->e_vm.vm_map.size/1024));
|
||||
(k->ki_p->ki_size/1024));
|
||||
}
|
||||
|
||||
void
|
||||
@ -456,7 +454,7 @@ rssize(k, ve)
|
||||
v = ve->var;
|
||||
/* XXX don't have info about shared */
|
||||
(void)printf("%*lu", v->width,
|
||||
(u_long)pgtok(KI_EPROC(k)->e_vm.vm_rssize));
|
||||
(u_long)pgtok(k->ki_p->ki_rssize));
|
||||
}
|
||||
|
||||
void
|
||||
@ -467,7 +465,7 @@ p_rssize(k, ve) /* doesn't account for text */
|
||||
VAR *v;
|
||||
|
||||
v = ve->var;
|
||||
(void)printf("%*ld", v->width, (long)pgtok(KI_EPROC(k)->e_vm.vm_rssize));
|
||||
(void)printf("%*ld", v->width, (long)pgtok(k->ki_p->ki_rssize));
|
||||
}
|
||||
|
||||
void
|
||||
@ -481,7 +479,7 @@ cputime(k, ve)
|
||||
char obuff[128];
|
||||
|
||||
v = ve->var;
|
||||
if (KI_PROC(k)->p_stat == SZOMB || !k->ki_u.u_valid) {
|
||||
if (k->ki_p->ki_stat == SZOMB || !k->ki_valid) {
|
||||
secs = 0;
|
||||
psecs = 0;
|
||||
} else {
|
||||
@ -490,13 +488,11 @@ cputime(k, ve)
|
||||
* fix this, but it is not 100% trivial (and interrupt
|
||||
* time fractions only work on the sparc anyway). XXX
|
||||
*/
|
||||
secs = KI_PROC(k)->p_runtime / 1000000;
|
||||
psecs = KI_PROC(k)->p_runtime % 1000000;
|
||||
secs = k->ki_p->ki_runtime / 1000000;
|
||||
psecs = k->ki_p->ki_runtime % 1000000;
|
||||
if (sumrusage) {
|
||||
secs += k->ki_u.u_cru.ru_utime.tv_sec +
|
||||
k->ki_u.u_cru.ru_stime.tv_sec;
|
||||
psecs += k->ki_u.u_cru.ru_utime.tv_usec +
|
||||
k->ki_u.u_cru.ru_stime.tv_usec;
|
||||
secs += k->ki_p->ki_childtime.tv_sec;
|
||||
psecs += k->ki_p->ki_childtime.tv_usec;
|
||||
}
|
||||
/*
|
||||
* round and scale to 100's
|
||||
@ -514,7 +510,6 @@ double
|
||||
getpcpu(k)
|
||||
KINFO *k;
|
||||
{
|
||||
struct proc *p;
|
||||
static int failure;
|
||||
|
||||
if (!nlistread)
|
||||
@ -522,16 +517,15 @@ getpcpu(k)
|
||||
if (failure)
|
||||
return (0.0);
|
||||
|
||||
p = KI_PROC(k);
|
||||
#define fxtofl(fixpt) ((double)(fixpt) / fscale)
|
||||
|
||||
/* XXX - I don't like this */
|
||||
if (p->p_swtime == 0 || (p->p_flag & P_INMEM) == 0)
|
||||
if (k->ki_p->ki_swtime == 0 || (k->ki_p->ki_flag & P_INMEM) == 0)
|
||||
return (0.0);
|
||||
if (rawcpu)
|
||||
return (100.0 * fxtofl(p->p_pctcpu));
|
||||
return (100.0 * fxtofl(p->p_pctcpu) /
|
||||
(1.0 - exp(p->p_swtime * log(fxtofl(ccpu)))));
|
||||
return (100.0 * fxtofl(k->ki_p->ki_pctcpu));
|
||||
return (100.0 * fxtofl(k->ki_p->ki_pctcpu) /
|
||||
(1.0 - exp(k->ki_p->ki_swtime * log(fxtofl(ccpu)))));
|
||||
}
|
||||
|
||||
void
|
||||
@ -550,8 +544,6 @@ getpmem(k)
|
||||
KINFO *k;
|
||||
{
|
||||
static int failure;
|
||||
struct proc *p;
|
||||
struct eproc *e;
|
||||
double fracmem;
|
||||
int szptudot;
|
||||
|
||||
@ -560,14 +552,12 @@ getpmem(k)
|
||||
if (failure)
|
||||
return (0.0);
|
||||
|
||||
p = KI_PROC(k);
|
||||
e = KI_EPROC(k);
|
||||
if ((p->p_flag & P_INMEM) == 0)
|
||||
if ((k->ki_p->ki_flag & P_INMEM) == 0)
|
||||
return (0.0);
|
||||
/* XXX want pmap ptpages, segtab, etc. (per architecture) */
|
||||
szptudot = UPAGES;
|
||||
/* XXX don't have info about shared */
|
||||
fracmem = ((float)e->e_vm.vm_rssize + szptudot)/mempages;
|
||||
fracmem = ((float)k->ki_p->ki_rssize + szptudot)/mempages;
|
||||
return (100.0 * fracmem);
|
||||
}
|
||||
|
||||
@ -591,7 +581,7 @@ pagein(k, ve)
|
||||
|
||||
v = ve->var;
|
||||
(void)printf("%*ld", v->width,
|
||||
k->ki_u.u_valid ? k->ki_u.u_ru.ru_majflt : 0);
|
||||
k->ki_valid ? k->ki_p->ki_rusage.ru_majflt : 0);
|
||||
}
|
||||
|
||||
void
|
||||
@ -614,7 +604,7 @@ tsize(k, ve)
|
||||
VAR *v;
|
||||
|
||||
v = ve->var;
|
||||
(void)printf("%*ld", v->width, (long)pgtok(KI_EPROC(k)->e_vm.vm_tsize));
|
||||
(void)printf("%*ld", v->width, (long)pgtok(k->ki_p->ki_tsize));
|
||||
}
|
||||
|
||||
void
|
||||
@ -628,7 +618,7 @@ rtprior(k, ve)
|
||||
unsigned prio, type;
|
||||
|
||||
v = ve->var;
|
||||
prtp = (struct rtprio *) ((char *)KI_PROC(k) + v->off);
|
||||
prtp = (struct rtprio *) ((char *)k + v->off);
|
||||
prio = prtp->prio;
|
||||
type = prtp->type;
|
||||
switch (type) {
|
||||
@ -702,39 +692,14 @@ printval(bp, v)
|
||||
}
|
||||
|
||||
void
|
||||
pvar(k, ve)
|
||||
kvar(k, ve)
|
||||
KINFO *k;
|
||||
VARENT *ve;
|
||||
{
|
||||
VAR *v;
|
||||
|
||||
v = ve->var;
|
||||
printval((char *)((char *)KI_PROC(k) + v->off), v);
|
||||
}
|
||||
|
||||
void
|
||||
evar(k, ve)
|
||||
KINFO *k;
|
||||
VARENT *ve;
|
||||
{
|
||||
VAR *v;
|
||||
|
||||
v = ve->var;
|
||||
printval((char *)((char *)KI_EPROC(k) + v->off), v);
|
||||
}
|
||||
|
||||
void
|
||||
uvar(k, ve)
|
||||
KINFO *k;
|
||||
VARENT *ve;
|
||||
{
|
||||
VAR *v;
|
||||
|
||||
v = ve->var;
|
||||
if (k->ki_u.u_valid)
|
||||
printval((char *)((char *)&k->ki_u + v->off), v);
|
||||
else
|
||||
(void)printf("%*s", v->width, "-");
|
||||
printval((char *)((char *)k->ki_p + v->off), v);
|
||||
}
|
||||
|
||||
void
|
||||
@ -745,8 +710,8 @@ rvar(k, ve)
|
||||
VAR *v;
|
||||
|
||||
v = ve->var;
|
||||
if (k->ki_u.u_valid)
|
||||
printval((char *)((char *)(&k->ki_u.u_ru) + v->off), v);
|
||||
if (k->ki_valid)
|
||||
printval((char *)((char *)(&k->ki_p->ki_rusage) + v->off), v);
|
||||
else
|
||||
(void)printf("%*s", v->width, "-");
|
||||
}
|
||||
|
37
bin/ps/ps.c
37
bin/ps/ps.c
@ -368,13 +368,12 @@ main(argc, argv)
|
||||
* for each proc, call each variable output function.
|
||||
*/
|
||||
for (i = lineno = 0; i < nentries; i++) {
|
||||
if (xflg == 0 && (KI_EPROC(&kinfo[i])->e_tdev == NODEV ||
|
||||
(KI_PROC(&kinfo[i])->p_flag & P_CONTROLT ) == 0))
|
||||
if (xflg == 0 && ((&kinfo[i])->ki_p->ki_tdev == NODEV ||
|
||||
((&kinfo[i])->ki_p->ki_flag & P_CONTROLT ) == 0))
|
||||
continue;
|
||||
if (nuids > 1) {
|
||||
for (uid = 0; uid < nuids; uid++)
|
||||
if (KI_EPROC(&kinfo[i])->e_ucred.cr_uid ==
|
||||
uids[uid])
|
||||
if ((&kinfo[i])->ki_p->ki_uid == uids[uid])
|
||||
break;
|
||||
if (uid == nuids)
|
||||
continue;
|
||||
@ -509,38 +508,32 @@ fmt(fn, ki, comm, maxlen)
|
||||
return (s);
|
||||
}
|
||||
|
||||
#define UREADOK(ki) (forceuread || (KI_PROC(ki)->p_flag & P_INMEM))
|
||||
#define UREADOK(ki) (forceuread || (ki->ki_p->ki_flag & P_INMEM))
|
||||
|
||||
static void
|
||||
saveuser(ki)
|
||||
KINFO *ki;
|
||||
{
|
||||
struct usave *usp;
|
||||
|
||||
usp = &ki->ki_u;
|
||||
|
||||
if (KI_PROC(ki)->p_flag & P_INMEM) {
|
||||
if (ki->ki_p->ki_flag & P_INMEM) {
|
||||
/*
|
||||
* The u-area might be swapped out, and we can't get
|
||||
* at it because we have a crashdump and no swap.
|
||||
* If it's here fill in these fields, otherwise, just
|
||||
* leave them 0.
|
||||
*/
|
||||
usp->u_start = KI_EPROC(ki)->e_stats.p_start;
|
||||
usp->u_ru = KI_EPROC(ki)->e_stats.p_ru;
|
||||
usp->u_cru = KI_EPROC(ki)->e_stats.p_cru;
|
||||
usp->u_valid = 1;
|
||||
ki->ki_valid = 1;
|
||||
} else
|
||||
usp->u_valid = 0;
|
||||
ki->ki_valid = 0;
|
||||
/*
|
||||
* save arguments if needed
|
||||
*/
|
||||
if (needcomm && (UREADOK(ki) || (KI_PROC(ki)->p_args != NULL))) {
|
||||
ki->ki_args = fmt(kvm_getargv, ki, KI_PROC(ki)->p_comm,
|
||||
if (needcomm && (UREADOK(ki) || (ki->ki_p->ki_args != NULL))) {
|
||||
ki->ki_args = fmt(kvm_getargv, ki, ki->ki_p->ki_comm,
|
||||
MAXCOMLEN);
|
||||
} else if (needcomm) {
|
||||
ki->ki_args = malloc(strlen(KI_PROC(ki)->p_comm) + 3);
|
||||
sprintf(ki->ki_args, "(%s)", KI_PROC(ki)->p_comm);
|
||||
ki->ki_args = malloc(strlen(ki->ki_p->ki_comm) + 3);
|
||||
sprintf(ki->ki_args, "(%s)", ki->ki_p->ki_comm);
|
||||
} else {
|
||||
ki->ki_args = NULL;
|
||||
}
|
||||
@ -559,16 +552,16 @@ pscomp(a, b)
|
||||
const void *a, *b;
|
||||
{
|
||||
int i;
|
||||
#define VSIZE(k) (KI_EPROC(k)->e_vm.vm_dsize + KI_EPROC(k)->e_vm.vm_ssize + \
|
||||
KI_EPROC(k)->e_vm.vm_tsize)
|
||||
#define VSIZE(k) ((k)->ki_p->ki_dsize + (k)->ki_p->ki_ssize + \
|
||||
(k)->ki_p->ki_tsize)
|
||||
|
||||
if (sortby == SORTCPU)
|
||||
return (getpcpu((KINFO *)b) - getpcpu((KINFO *)a));
|
||||
if (sortby == SORTMEM)
|
||||
return (VSIZE((KINFO *)b) - VSIZE((KINFO *)a));
|
||||
i = KI_EPROC((KINFO *)a)->e_tdev - KI_EPROC((KINFO *)b)->e_tdev;
|
||||
i = ((KINFO *)a)->ki_p->ki_tdev - ((KINFO *)b)->ki_p->ki_tdev;
|
||||
if (i == 0)
|
||||
i = KI_PROC((KINFO *)a)->p_pid - KI_PROC((KINFO *)b)->p_pid;
|
||||
i = ((KINFO *)a)->ki_p->ki_pid - ((KINFO *)b)->ki_p->ki_pid;
|
||||
return (i);
|
||||
}
|
||||
|
||||
|
19
bin/ps/ps.h
19
bin/ps/ps.h
@ -37,22 +37,11 @@
|
||||
#define UNLIMITED 0 /* unlimited terminal width */
|
||||
enum type { CHAR, UCHAR, SHORT, USHORT, INT, UINT, LONG, ULONG, KPTR };
|
||||
|
||||
struct usave {
|
||||
struct timeval u_start;
|
||||
struct rusage u_ru;
|
||||
struct rusage u_cru;
|
||||
char u_acflag;
|
||||
char u_valid;
|
||||
};
|
||||
|
||||
#define KI_PROC(ki) (&(ki)->ki_p->kp_proc)
|
||||
#define KI_EPROC(ki) (&(ki)->ki_p->kp_eproc)
|
||||
|
||||
typedef struct kinfo {
|
||||
struct kinfo_proc *ki_p; /* proc structure */
|
||||
struct usave ki_u; /* interesting parts of user */
|
||||
struct kinfo_proc *ki_p; /* kinfo_proc structure */
|
||||
char *ki_args; /* exec args */
|
||||
char *ki_env; /* environment */
|
||||
int ki_valid; /* 1 => uarea stuff valid */
|
||||
} KINFO;
|
||||
|
||||
/* Variables. */
|
||||
@ -77,8 +66,8 @@ typedef struct var {
|
||||
short width; /* printing width */
|
||||
/*
|
||||
* The following (optional) elements are hooks for passing information
|
||||
* to the generic output routines: pvar, evar, uvar (those which print
|
||||
* simple elements from well known structures: proc, eproc, usave)
|
||||
* to the generic output routine pvar (which prints simple elements
|
||||
* from the well known kinfo_proc structure).
|
||||
*/
|
||||
int off; /* offset in structure */
|
||||
enum type type; /* type of element */
|
||||
|
@ -89,7 +89,7 @@ kvm_t *kvm_openfiles
|
||||
__P((const char *, const char *, const char *, int, char *));
|
||||
ssize_t kvm_read __P((kvm_t *, unsigned long, void *, size_t));
|
||||
ssize_t kvm_uread
|
||||
__P((kvm_t *, const struct proc *, unsigned long, char *, size_t));
|
||||
__P((kvm_t *, struct kinfo_proc *, unsigned long, char *, size_t));
|
||||
ssize_t kvm_write __P((kvm_t *, unsigned long, const void *, size_t));
|
||||
__END_DECLS
|
||||
|
||||
|
@ -109,21 +109,36 @@ kvm_proclist(kd, what, arg, p, bp, maxcnt)
|
||||
int maxcnt;
|
||||
{
|
||||
register int cnt = 0;
|
||||
struct eproc eproc;
|
||||
struct kinfo_proc kinfo_proc, *kp;
|
||||
struct pgrp pgrp;
|
||||
struct session sess;
|
||||
struct tty tty;
|
||||
struct vmspace vmspace;
|
||||
struct procsig procsig;
|
||||
struct pcred pcred;
|
||||
struct pstats pstats;
|
||||
struct ucred ucred;
|
||||
struct proc proc;
|
||||
struct proc pproc;
|
||||
|
||||
kp = &kinfo_proc;
|
||||
kp->ki_structsize = sizeof(kinfo_proc);
|
||||
for (; cnt < maxcnt && p != NULL; p = proc.p_list.le_next) {
|
||||
if (KREAD(kd, (u_long)p, &proc)) {
|
||||
_kvm_err(kd, kd->program, "can't read proc at %x", p);
|
||||
return (-1);
|
||||
}
|
||||
if (KREAD(kd, (u_long)proc.p_cred, &eproc.e_pcred) == 0)
|
||||
(void)(KREAD(kd, (u_long)eproc.e_pcred.pc_ucred,
|
||||
&eproc.e_ucred));
|
||||
if (KREAD(kd, (u_long)proc.p_cred, &pcred) == 0) {
|
||||
kp->ki_ruid = pcred.p_ruid;
|
||||
kp->ki_svuid = pcred.p_svuid;
|
||||
kp->ki_rgid = pcred.p_rgid;
|
||||
kp->ki_svgid = pcred.p_svgid;
|
||||
(void)(KREAD(kd, (u_long)pcred.pc_ucred, &ucred));
|
||||
kp->ki_ngroups = ucred.cr_ngroups;
|
||||
bcopy(ucred.cr_groups, kp->ki_groups,
|
||||
NGROUPS * sizeof(gid_t));
|
||||
kp->ki_uid = ucred.cr_uid;
|
||||
}
|
||||
|
||||
switch(what) {
|
||||
|
||||
@ -133,12 +148,12 @@ kvm_proclist(kd, what, arg, p, bp, maxcnt)
|
||||
break;
|
||||
|
||||
case KERN_PROC_UID:
|
||||
if (eproc.e_ucred.cr_uid != (uid_t)arg)
|
||||
if (kp->ki_uid != (uid_t)arg)
|
||||
continue;
|
||||
break;
|
||||
|
||||
case KERN_PROC_RUID:
|
||||
if (eproc.e_pcred.p_ruid != (uid_t)arg)
|
||||
if (kp->ki_ruid != (uid_t)arg)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
@ -152,43 +167,74 @@ kvm_proclist(kd, what, arg, p, bp, maxcnt)
|
||||
return (-1);
|
||||
}
|
||||
/*
|
||||
* gather eproc
|
||||
* gather kinfo_proc
|
||||
*/
|
||||
eproc.e_paddr = p;
|
||||
kp->ki_paddr = p;
|
||||
kp->ki_addr = proc.p_addr;
|
||||
kp->ki_args = proc.p_args;
|
||||
kp->ki_tracep = proc.p_tracep;
|
||||
kp->ki_textvp = proc.p_textvp;
|
||||
kp->ki_fd = proc.p_fd;
|
||||
kp->ki_vmspace = proc.p_vmspace;
|
||||
if (proc.p_procsig != NULL) {
|
||||
if (KREAD(kd, (u_long)proc.p_procsig, &procsig)) {
|
||||
_kvm_err(kd, kd->program,
|
||||
"can't read procsig at %x", proc.p_procsig);
|
||||
return (-1);
|
||||
}
|
||||
kp->ki_sigignore = procsig.ps_sigignore;
|
||||
kp->ki_sigcatch = procsig.ps_sigcatch;
|
||||
}
|
||||
if ((proc.p_flag & P_INMEM) && proc.p_stats != NULL) {
|
||||
if (KREAD(kd, (u_long)proc.p_stats, &pstats)) {
|
||||
_kvm_err(kd, kd->program,
|
||||
"can't read stats at %x", proc.p_stats);
|
||||
return (-1);
|
||||
}
|
||||
kp->ki_start = pstats.p_start;
|
||||
kp->ki_rusage = pstats.p_ru;
|
||||
kp->ki_childtime.tv_sec = pstats.p_cru.ru_utime.tv_sec +
|
||||
pstats.p_cru.ru_stime.tv_sec;
|
||||
kp->ki_childtime.tv_usec =
|
||||
pstats.p_cru.ru_utime.tv_usec +
|
||||
pstats.p_cru.ru_stime.tv_usec;
|
||||
}
|
||||
if (KREAD(kd, (u_long)proc.p_pgrp, &pgrp)) {
|
||||
_kvm_err(kd, kd->program, "can't read pgrp at %x",
|
||||
proc.p_pgrp);
|
||||
return (-1);
|
||||
}
|
||||
if (proc.p_oppid)
|
||||
eproc.e_ppid = proc.p_oppid;
|
||||
kp->ki_ppid = proc.p_oppid;
|
||||
else if (proc.p_pptr) {
|
||||
if (KREAD(kd, (u_long)proc.p_pptr, &pproc)) {
|
||||
_kvm_err(kd, kd->program, "can't read pproc at %x",
|
||||
proc.p_pptr);
|
||||
return (-1);
|
||||
}
|
||||
eproc.e_ppid = pproc.p_pid;
|
||||
if (KREAD(kd, (u_long)proc.p_pptr, &pproc)) {
|
||||
_kvm_err(kd, kd->program,
|
||||
"can't read pproc at %x", proc.p_pptr);
|
||||
return (-1);
|
||||
}
|
||||
kp->ki_ppid = pproc.p_pid;
|
||||
} else
|
||||
eproc.e_ppid = 0;
|
||||
eproc.e_sess = pgrp.pg_session;
|
||||
eproc.e_pgid = pgrp.pg_id;
|
||||
eproc.e_jobc = pgrp.pg_jobc;
|
||||
kp->ki_ppid = 0;
|
||||
kp->ki_pgid = pgrp.pg_id;
|
||||
kp->ki_jobc = pgrp.pg_jobc;
|
||||
if (KREAD(kd, (u_long)pgrp.pg_session, &sess)) {
|
||||
_kvm_err(kd, kd->program, "can't read session at %x",
|
||||
pgrp.pg_session);
|
||||
return (-1);
|
||||
}
|
||||
(void)memcpy(eproc.e_login, sess.s_login,
|
||||
sizeof(eproc.e_login));
|
||||
kp->ki_sid = sess.s_sid;
|
||||
(void)memcpy(kp->ki_login, sess.s_login,
|
||||
sizeof(kp->ki_login));
|
||||
kp->ki_kiflag = sess.s_ttyvp ? KI_CTTY : 0;
|
||||
if (sess.s_leader == p)
|
||||
kp->ki_kiflag |= KI_SLEADER;
|
||||
if ((proc.p_flag & P_CONTROLT) && sess.s_ttyp != NULL) {
|
||||
if (KREAD(kd, (u_long)sess.s_ttyp, &tty)) {
|
||||
_kvm_err(kd, kd->program,
|
||||
"can't read tty at %x", sess.s_ttyp);
|
||||
return (-1);
|
||||
}
|
||||
eproc.e_tdev = tty.t_dev;
|
||||
eproc.e_tsess = tty.t_session;
|
||||
kp->ki_tdev = tty.t_dev;
|
||||
if (tty.t_pgrp != NULL) {
|
||||
if (KREAD(kd, (u_long)tty.t_pgrp, &pgrp)) {
|
||||
_kvm_err(kd, kd->program,
|
||||
@ -196,47 +242,90 @@ kvm_proclist(kd, what, arg, p, bp, maxcnt)
|
||||
tty.t_pgrp);
|
||||
return (-1);
|
||||
}
|
||||
eproc.e_tpgid = pgrp.pg_id;
|
||||
kp->ki_tpgid = pgrp.pg_id;
|
||||
} else
|
||||
eproc.e_tpgid = -1;
|
||||
kp->ki_tpgid = -1;
|
||||
if (tty.t_session != NULL) {
|
||||
if (KREAD(kd, (u_long)tty.t_session, &sess)) {
|
||||
_kvm_err(kd, kd->program,
|
||||
"can't read session at %x",
|
||||
tty.t_session);
|
||||
return (-1);
|
||||
}
|
||||
kp->ki_tsid = sess.s_sid;
|
||||
}
|
||||
} else
|
||||
eproc.e_tdev = NODEV;
|
||||
eproc.e_flag = sess.s_ttyvp ? EPROC_CTTY : 0;
|
||||
if (sess.s_leader == p)
|
||||
eproc.e_flag |= EPROC_SLEADER;
|
||||
kp->ki_tdev = NODEV;
|
||||
if (proc.p_wmesg)
|
||||
(void)kvm_read(kd, (u_long)proc.p_wmesg,
|
||||
eproc.e_wmesg, WMESGLEN);
|
||||
kp->ki_wmesg, WMESGLEN);
|
||||
|
||||
#ifdef sparc
|
||||
(void)kvm_read(kd, (u_long)&proc.p_vmspace->vm_rssize,
|
||||
(char *)&eproc.e_vm.vm_rssize,
|
||||
sizeof(eproc.e_vm.vm_rssize));
|
||||
(char *)&kp->ki_rssize,
|
||||
sizeof(kp->ki_rssize));
|
||||
(void)kvm_read(kd, (u_long)&proc.p_vmspace->vm_tsize,
|
||||
(char *)&eproc.e_vm.vm_tsize,
|
||||
3 * sizeof(eproc.e_vm.vm_rssize)); /* XXX */
|
||||
(char *)&kp->ki_tsize,
|
||||
3 * sizeof(kp->ki_rssize)); /* XXX */
|
||||
#else
|
||||
(void)kvm_read(kd, (u_long)proc.p_vmspace,
|
||||
(char *)&eproc.e_vm, sizeof(eproc.e_vm));
|
||||
(char *)&vmspace, sizeof(vmspace));
|
||||
kp->ki_size = vmspace.vm_map.size;
|
||||
kp->ki_rssize = vmspace.vm_swrss; /* XXX */
|
||||
kp->ki_swrss = vmspace.vm_swrss;
|
||||
kp->ki_tsize = vmspace.vm_tsize;
|
||||
kp->ki_dsize = vmspace.vm_dsize;
|
||||
kp->ki_ssize = vmspace.vm_ssize;
|
||||
#endif
|
||||
eproc.e_xsize = eproc.e_xrssize = 0;
|
||||
eproc.e_xccount = eproc.e_xswrss = 0;
|
||||
|
||||
switch (what) {
|
||||
|
||||
case KERN_PROC_PGRP:
|
||||
if (eproc.e_pgid != (pid_t)arg)
|
||||
if (kp->ki_pgid != (pid_t)arg)
|
||||
continue;
|
||||
break;
|
||||
|
||||
case KERN_PROC_TTY:
|
||||
if ((proc.p_flag & P_CONTROLT) == 0 ||
|
||||
eproc.e_tdev != (dev_t)arg)
|
||||
kp->ki_tdev != (dev_t)arg)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
bcopy(&proc, &bp->kp_proc, sizeof(proc));
|
||||
bcopy(&eproc, &bp->kp_eproc, sizeof(eproc));
|
||||
if (proc.p_comm[0] != 0) {
|
||||
strncpy(kp->ki_comm, proc.p_comm, MAXCOMLEN);
|
||||
kp->ki_comm[MAXCOMLEN] = 0;
|
||||
}
|
||||
if (proc.p_blocked != 0) {
|
||||
kp->ki_kiflag |= KI_MTXBLOCK;
|
||||
if (proc.p_mtxname)
|
||||
(void)kvm_read(kd, (u_long)proc.p_mtxname,
|
||||
kp->ki_mtxname, MTXNAMELEN);
|
||||
kp->ki_mtxname[MTXNAMELEN] = 0;
|
||||
}
|
||||
kp->ki_rtprio = proc.p_rtprio;
|
||||
kp->ki_runtime = proc.p_runtime;
|
||||
kp->ki_pid = proc.p_pid;
|
||||
kp->ki_siglist = proc.p_siglist;
|
||||
kp->ki_sigmask = proc.p_sigmask;
|
||||
kp->ki_xstat = proc.p_xstat;
|
||||
kp->ki_acflag = proc.p_acflag;
|
||||
kp->ki_pctcpu = proc.p_pctcpu;
|
||||
kp->ki_estcpu = proc.p_estcpu;
|
||||
kp->ki_slptime = proc.p_slptime;
|
||||
kp->ki_swtime = proc.p_swtime;
|
||||
kp->ki_flag = proc.p_flag;
|
||||
kp->ki_wchan = proc.p_wchan;
|
||||
kp->ki_traceflag = proc.p_traceflag;
|
||||
kp->ki_priority = proc.p_priority;
|
||||
kp->ki_usrpri = proc.p_usrpri;
|
||||
kp->ki_nativepri = proc.p_nativepri;
|
||||
kp->ki_stat = proc.p_stat;
|
||||
kp->ki_nice = proc.p_nice;
|
||||
kp->ki_lock = proc.p_lock;
|
||||
kp->ki_rqindex = proc.p_rqindex;
|
||||
kp->ki_oncpu = proc.p_oncpu;
|
||||
kp->ki_lastcpu = proc.p_lastcpu;
|
||||
bcopy(&kinfo_proc, bp, sizeof(kinfo_proc));
|
||||
++bp;
|
||||
++cnt;
|
||||
}
|
||||
@ -319,13 +408,14 @@ kvm_getprocs(kd, op, arg, cnt)
|
||||
_kvm_syserr(kd, kd->program, "kvm_getprocs");
|
||||
return (0);
|
||||
}
|
||||
if (size % sizeof(struct kinfo_proc) != 0) {
|
||||
if (kd->procbase->ki_structsize != sizeof(struct kinfo_proc)) {
|
||||
_kvm_err(kd, kd->program,
|
||||
"proc size mismatch (%d total, %d chunks)",
|
||||
size, sizeof(struct kinfo_proc));
|
||||
"kinfo_proc size mismatch (expected %d, got %d)",
|
||||
sizeof(struct kinfo_proc),
|
||||
kd->procbase->ki_structsize);
|
||||
return (0);
|
||||
}
|
||||
nprocs = size / sizeof(struct kinfo_proc);
|
||||
nprocs = size / kd->procbase->ki_structsize;
|
||||
} else {
|
||||
struct nlist nl[4], *p;
|
||||
|
||||
@ -391,15 +481,15 @@ _kvm_realloc(kd, p, n)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Read in an argument vector from the user address space of process p.
|
||||
* Read in an argument vector from the user address space of process kp.
|
||||
* addr if the user-space base address of narg null-terminated contiguous
|
||||
* strings. This is used to read in both the command arguments and
|
||||
* environment strings. Read at most maxcnt characters of strings.
|
||||
*/
|
||||
static char **
|
||||
kvm_argv(kd, p, addr, narg, maxcnt)
|
||||
kvm_argv(kd, kp, addr, narg, maxcnt)
|
||||
kvm_t *kd;
|
||||
const struct proc *p;
|
||||
struct kinfo_proc *kp;
|
||||
register u_long addr;
|
||||
register int narg;
|
||||
register int maxcnt;
|
||||
@ -458,7 +548,7 @@ kvm_argv(kd, p, addr, narg, maxcnt)
|
||||
|
||||
/* Pull in the target process'es argv vector */
|
||||
cc = sizeof(char *) * narg;
|
||||
if (kvm_uread(kd, p, addr, (char *)kd->argv, cc) != cc)
|
||||
if (kvm_uread(kd, kp, addr, (char *)kd->argv, cc) != cc)
|
||||
return (0);
|
||||
/*
|
||||
* ap : saved start address of string we're working on in kd->argspc
|
||||
@ -486,7 +576,7 @@ kvm_argv(kd, p, addr, narg, maxcnt)
|
||||
|
||||
/* is it the same page as the last one? */
|
||||
if (addr != oaddr) {
|
||||
if (kvm_uread(kd, p, addr, kd->argbuf, PAGE_SIZE) !=
|
||||
if (kvm_uread(kd, kp, addr, kd->argbuf, PAGE_SIZE) !=
|
||||
PAGE_SIZE)
|
||||
return (0);
|
||||
oaddr = addr;
|
||||
@ -598,35 +688,32 @@ ps_str_e(p, addr, n)
|
||||
* being wrong are very low.
|
||||
*/
|
||||
static int
|
||||
proc_verify(kd, kernp, p)
|
||||
kvm_t *kd;
|
||||
u_long kernp;
|
||||
const struct proc *p;
|
||||
proc_verify(curkp)
|
||||
struct kinfo_proc *curkp;
|
||||
{
|
||||
struct kinfo_proc kp;
|
||||
struct kinfo_proc newkp;
|
||||
int mib[4];
|
||||
size_t len;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_PID;
|
||||
mib[3] = p->p_pid;
|
||||
len = sizeof(kp);
|
||||
if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1)
|
||||
mib[3] = curkp->ki_pid;
|
||||
len = sizeof(newkp);
|
||||
if (sysctl(mib, 4, &newkp, &len, NULL, 0) == -1)
|
||||
return (0);
|
||||
return (p->p_pid == kp.kp_proc.p_pid &&
|
||||
(kp.kp_proc.p_stat != SZOMB || p->p_stat == SZOMB));
|
||||
return (curkp->ki_pid == newkp.ki_pid &&
|
||||
(newkp.ki_stat != SZOMB || curkp->ki_stat == SZOMB));
|
||||
}
|
||||
|
||||
static char **
|
||||
kvm_doargv(kd, kp, nchr, info)
|
||||
kvm_t *kd;
|
||||
const struct kinfo_proc *kp;
|
||||
struct kinfo_proc *kp;
|
||||
int nchr;
|
||||
void (*info)(struct ps_strings *, u_long *, int *);
|
||||
{
|
||||
register const struct proc *p = &kp->kp_proc;
|
||||
register char **ap;
|
||||
char **ap;
|
||||
u_long addr;
|
||||
int cnt;
|
||||
static struct ps_strings arginfo;
|
||||
@ -643,20 +730,19 @@ kvm_doargv(kd, kp, nchr, info)
|
||||
/*
|
||||
* Pointers are stored at the top of the user stack.
|
||||
*/
|
||||
if (p->p_stat == SZOMB ||
|
||||
kvm_uread(kd, p, ps_strings, (char *)&arginfo,
|
||||
if (kp->ki_stat == SZOMB ||
|
||||
kvm_uread(kd, kp, ps_strings, (char *)&arginfo,
|
||||
sizeof(arginfo)) != sizeof(arginfo))
|
||||
return (0);
|
||||
|
||||
(*info)(&arginfo, &addr, &cnt);
|
||||
if (cnt == 0)
|
||||
return (0);
|
||||
ap = kvm_argv(kd, p, addr, cnt, nchr);
|
||||
ap = kvm_argv(kd, kp, addr, cnt, nchr);
|
||||
/*
|
||||
* For live kernels, make sure this process didn't go away.
|
||||
*/
|
||||
if (ap != 0 && ISALIVE(kd) &&
|
||||
!proc_verify(kd, (u_long)kp->kp_eproc.e_paddr, p))
|
||||
if (ap != 0 && ISALIVE(kd) && !proc_verify(kp))
|
||||
ap = 0;
|
||||
return (ap);
|
||||
}
|
||||
@ -702,7 +788,7 @@ kvm_getargv(kd, kp, nchr)
|
||||
oid[0] = CTL_KERN;
|
||||
oid[1] = KERN_PROC;
|
||||
oid[2] = KERN_PROC_ARGS;
|
||||
oid[3] = kp->kp_proc.p_pid;
|
||||
oid[3] = kp->ki_pid;
|
||||
bufsz = buflen;
|
||||
i = sysctl(oid, 4, buf, &bufsz, 0, 0);
|
||||
if (i == 0 && bufsz > 0) {
|
||||
@ -721,7 +807,7 @@ kvm_getargv(kd, kp, nchr)
|
||||
return (bufp);
|
||||
}
|
||||
}
|
||||
if (kp->kp_proc.p_flag & P_SYSTEM)
|
||||
if (kp->ki_flag & P_SYSTEM)
|
||||
return (NULL);
|
||||
return (kvm_doargv(kd, kp, nchr, ps_str_a));
|
||||
}
|
||||
@ -739,9 +825,9 @@ kvm_getenvv(kd, kp, nchr)
|
||||
* Read from user space. The user context is given by p.
|
||||
*/
|
||||
ssize_t
|
||||
kvm_uread(kd, p, uva, buf, len)
|
||||
kvm_uread(kd, kp, uva, buf, len)
|
||||
kvm_t *kd;
|
||||
register const struct proc *p;
|
||||
struct kinfo_proc *kp;
|
||||
register u_long uva;
|
||||
register char *buf;
|
||||
register size_t len;
|
||||
@ -757,7 +843,7 @@ kvm_uread(kd, p, uva, buf, len)
|
||||
return (0);
|
||||
}
|
||||
|
||||
sprintf(procfile, "/proc/%d/mem", p->p_pid);
|
||||
sprintf(procfile, "/proc/%d/mem", kp->ki_pid);
|
||||
fd = open(procfile, O_RDONLY, 0);
|
||||
if (fd < 0) {
|
||||
_kvm_err(kd, kd->program, "cannot open %s", procfile);
|
||||
|
@ -254,8 +254,7 @@ aout_coredump(p, vp, limit)
|
||||
|
||||
if (ctob(UPAGES + vm->vm_dsize + vm->vm_ssize) >= limit)
|
||||
return (EFAULT);
|
||||
bcopy(p, &p->p_addr->u_kproc.kp_proc, sizeof(struct proc));
|
||||
fill_eproc(p, &p->p_addr->u_kproc.kp_eproc);
|
||||
fill_kinfo_proc(p, &p->p_addr->u_kproc);
|
||||
error = cpu_coredump(p, vp, cred);
|
||||
if (error == 0)
|
||||
error = vn_rdwr(UIO_WRITE, vp, vm->vm_daddr,
|
||||
|
@ -90,6 +90,13 @@ procinit()
|
||||
pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash);
|
||||
proc_zone = zinit("PROC", sizeof (struct proc), 0, 0, 5);
|
||||
uihashinit();
|
||||
/*
|
||||
* This should really be a compile time warning, but I do
|
||||
* not know of any way to do that...
|
||||
*/
|
||||
if (sizeof(struct kinfo_proc) != KINFO_PROC_SIZE)
|
||||
printf("WARNING: size of kinfo_proc (%d) should be %d!!!\n",
|
||||
sizeof(struct kinfo_proc), KINFO_PROC_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -352,64 +359,118 @@ DB_SHOW_COMMAND(pgrpdump, pgrpdump)
|
||||
#endif /* DDB */
|
||||
|
||||
/*
|
||||
* Fill in an eproc structure for the specified process.
|
||||
* Fill in an kinfo_proc structure for the specified process.
|
||||
*/
|
||||
void
|
||||
fill_eproc(p, ep)
|
||||
register struct proc *p;
|
||||
register struct eproc *ep;
|
||||
fill_kinfo_proc(p, kp)
|
||||
struct proc *p;
|
||||
struct kinfo_proc *kp;
|
||||
{
|
||||
register struct tty *tp;
|
||||
struct tty *tp;
|
||||
struct session *sp;
|
||||
|
||||
bzero(ep, sizeof(*ep));
|
||||
bzero(kp, sizeof(*kp));
|
||||
|
||||
ep->e_paddr = p;
|
||||
kp->ki_structsize = sizeof(*kp);
|
||||
kp->ki_paddr = p;
|
||||
kp->ki_addr = p->p_addr;
|
||||
kp->ki_args = p->p_args;
|
||||
kp->ki_tracep = p->p_tracep;
|
||||
kp->ki_textvp = p->p_textvp;
|
||||
kp->ki_fd = p->p_fd;
|
||||
kp->ki_vmspace = p->p_vmspace;
|
||||
if (p->p_cred) {
|
||||
ep->e_pcred = *p->p_cred;
|
||||
if (p->p_ucred)
|
||||
ep->e_ucred = *p->p_ucred;
|
||||
kp->ki_uid = p->p_cred->pc_ucred->cr_uid;
|
||||
kp->ki_ruid = p->p_cred->p_ruid;
|
||||
kp->ki_svuid = p->p_cred->p_svuid;
|
||||
kp->ki_ngroups = p->p_cred->pc_ucred->cr_ngroups;
|
||||
bcopy(p->p_cred->pc_ucred->cr_groups, kp->ki_groups,
|
||||
NGROUPS * sizeof(gid_t));
|
||||
kp->ki_rgid = p->p_cred->p_rgid;
|
||||
kp->ki_svgid = p->p_cred->p_svgid;
|
||||
}
|
||||
if (p->p_procsig) {
|
||||
ep->e_procsig = *p->p_procsig;
|
||||
kp->ki_sigignore = p->p_procsig->ps_sigignore;
|
||||
kp->ki_sigcatch = p->p_procsig->ps_sigcatch;
|
||||
}
|
||||
if (p->p_stat != SIDL && p->p_stat != SZOMB && p->p_vmspace != NULL) {
|
||||
register struct vmspace *vm = p->p_vmspace;
|
||||
ep->e_vm = *vm;
|
||||
ep->e_vm.vm_rssize = vmspace_resident_count(vm); /*XXX*/
|
||||
}
|
||||
if ((p->p_flag & P_INMEM) && p->p_stats)
|
||||
ep->e_stats = *p->p_stats;
|
||||
if (p->p_pptr)
|
||||
ep->e_ppid = p->p_pptr->p_pid;
|
||||
if (p->p_pgrp) {
|
||||
ep->e_pgid = p->p_pgrp->pg_id;
|
||||
ep->e_jobc = p->p_pgrp->pg_jobc;
|
||||
ep->e_sess = p->p_pgrp->pg_session;
|
||||
struct vmspace *vm = p->p_vmspace;
|
||||
|
||||
if (ep->e_sess) {
|
||||
bcopy(ep->e_sess->s_login, ep->e_login, sizeof(ep->e_login));
|
||||
if (ep->e_sess->s_ttyvp)
|
||||
ep->e_flag = EPROC_CTTY;
|
||||
if (p->p_session && SESS_LEADER(p))
|
||||
ep->e_flag |= EPROC_SLEADER;
|
||||
kp->ki_size = vm->vm_map.size;
|
||||
kp->ki_rssize = vmspace_resident_count(vm); /*XXX*/
|
||||
kp->ki_swrss = vm->vm_swrss;
|
||||
kp->ki_tsize = vm->vm_tsize;
|
||||
kp->ki_dsize = vm->vm_dsize;
|
||||
kp->ki_ssize = vm->vm_ssize;
|
||||
}
|
||||
if ((p->p_flag & P_INMEM) && p->p_stats) {
|
||||
kp->ki_start = p->p_stats->p_start;
|
||||
kp->ki_rusage = p->p_stats->p_ru;
|
||||
kp->ki_childtime.tv_sec = p->p_stats->p_cru.ru_utime.tv_sec +
|
||||
p->p_stats->p_cru.ru_stime.tv_sec;
|
||||
kp->ki_childtime.tv_usec = p->p_stats->p_cru.ru_utime.tv_usec +
|
||||
p->p_stats->p_cru.ru_stime.tv_usec;
|
||||
}
|
||||
kp->ki_rtprio = p->p_rtprio;
|
||||
kp->ki_runtime = p->p_runtime;
|
||||
kp->ki_pid = p->p_pid;
|
||||
if (p->p_pptr)
|
||||
kp->ki_ppid = p->p_pptr->p_pid;
|
||||
sp = NULL;
|
||||
if (p->p_pgrp) {
|
||||
kp->ki_pgid = p->p_pgrp->pg_id;
|
||||
kp->ki_jobc = p->p_pgrp->pg_jobc;
|
||||
sp = p->p_pgrp->pg_session;
|
||||
|
||||
if (sp != NULL) {
|
||||
kp->ki_sid = sp->s_sid;
|
||||
bcopy(sp->s_login, kp->ki_login, sizeof(kp->ki_login));
|
||||
if (sp->s_ttyvp)
|
||||
kp->ki_kiflag = KI_CTTY;
|
||||
if (SESS_LEADER(p))
|
||||
kp->ki_kiflag |= KI_SLEADER;
|
||||
}
|
||||
}
|
||||
if ((p->p_flag & P_CONTROLT) &&
|
||||
(ep->e_sess != NULL) &&
|
||||
((tp = ep->e_sess->s_ttyp) != NULL)) {
|
||||
ep->e_tdev = dev2udev(tp->t_dev);
|
||||
ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
|
||||
ep->e_tsess = tp->t_session;
|
||||
if ((p->p_flag & P_CONTROLT) && sp && ((tp = sp->s_ttyp) != NULL)) {
|
||||
kp->ki_tdev = dev2udev(tp->t_dev);
|
||||
kp->ki_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
|
||||
if (tp->t_session)
|
||||
kp->ki_tsid = tp->t_session->s_sid;
|
||||
} else
|
||||
ep->e_tdev = NOUDEV;
|
||||
kp->ki_tdev = NOUDEV;
|
||||
if (p->p_wmesg) {
|
||||
strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN);
|
||||
ep->e_wmesg[WMESGLEN] = 0;
|
||||
strncpy(kp->ki_wmesg, p->p_wmesg, WMESGLEN);
|
||||
kp->ki_wmesg[WMESGLEN] = 0;
|
||||
}
|
||||
if (p->p_mtxname) {
|
||||
strncpy(ep->e_mtxname, p->p_mtxname, MTXNAMELEN);
|
||||
ep->e_mtxname[MTXNAMELEN] = 0;
|
||||
if (p->p_comm[0] != 0) {
|
||||
strncpy(kp->ki_comm, p->p_comm, MAXCOMLEN);
|
||||
kp->ki_comm[MAXCOMLEN] = 0;
|
||||
}
|
||||
if (p->p_blocked != 0) {
|
||||
kp->ki_kiflag |= KI_MTXBLOCK;
|
||||
strncpy(kp->ki_mtxname, p->p_mtxname, MTXNAMELEN);
|
||||
kp->ki_wmesg[MTXNAMELEN] = 0;
|
||||
}
|
||||
kp->ki_siglist = p->p_siglist;
|
||||
kp->ki_sigmask = p->p_sigmask;
|
||||
kp->ki_xstat = p->p_xstat;
|
||||
kp->ki_acflag = p->p_acflag;
|
||||
kp->ki_pctcpu = p->p_pctcpu;
|
||||
kp->ki_estcpu = p->p_estcpu;
|
||||
kp->ki_slptime = p->p_slptime;
|
||||
kp->ki_swtime = p->p_swtime;
|
||||
kp->ki_flag = p->p_flag;
|
||||
kp->ki_wchan = p->p_wchan;
|
||||
kp->ki_traceflag = p->p_traceflag;
|
||||
kp->ki_priority = p->p_priority;
|
||||
kp->ki_usrpri = p->p_usrpri;
|
||||
kp->ki_nativepri = p->p_nativepri;
|
||||
kp->ki_stat = p->p_stat;
|
||||
kp->ki_nice = p->p_nice;
|
||||
kp->ki_lock = p->p_lock;
|
||||
kp->ki_rqindex = p->p_rqindex;
|
||||
kp->ki_oncpu = p->p_oncpu;
|
||||
kp->ki_lastcpu = p->p_lastcpu;
|
||||
}
|
||||
|
||||
static struct proc *
|
||||
@ -427,15 +488,12 @@ zpfind(pid_t pid)
|
||||
static int
|
||||
sysctl_out_proc(struct proc *p, struct sysctl_req *req, int doingzomb)
|
||||
{
|
||||
struct eproc eproc;
|
||||
struct kinfo_proc kinfo_proc;
|
||||
int error;
|
||||
pid_t pid = p->p_pid;
|
||||
|
||||
fill_eproc(p, &eproc);
|
||||
error = SYSCTL_OUT(req,(caddr_t)p, sizeof(struct proc));
|
||||
if (error)
|
||||
return (error);
|
||||
error = SYSCTL_OUT(req,(caddr_t)&eproc, sizeof(eproc));
|
||||
fill_kinfo_proc(p, &kinfo_proc);
|
||||
error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc, sizeof(kinfo_proc));
|
||||
if (error)
|
||||
return (error);
|
||||
if (!doingzomb && pid && (pfind(pid) != p))
|
||||
|
@ -339,7 +339,7 @@ ptrace(curp, uap)
|
||||
}
|
||||
|
||||
if (uap->addr != (caddr_t)1) {
|
||||
fill_eproc (p, &p->p_addr->u_kproc.kp_eproc);
|
||||
fill_kinfo_proc (p, &p->p_addr->u_kproc);
|
||||
if ((error = ptrace_set_pc (p,
|
||||
(u_long)(uintfptr_t)uap->addr))) {
|
||||
PRELE(p);
|
||||
@ -428,8 +428,7 @@ ptrace(curp, uap)
|
||||
error = 0;
|
||||
PHOLD(p); /* user had damn well better be incore! */
|
||||
if (p->p_flag & P_INMEM) {
|
||||
p->p_addr->u_kproc.kp_proc = *p;
|
||||
fill_eproc (p, &p->p_addr->u_kproc.kp_eproc);
|
||||
fill_kinfo_proc (p, &p->p_addr->u_kproc);
|
||||
curp->p_retval[0] = *(int *)
|
||||
((uintptr_t)p->p_addr + (uintptr_t)uap->addr);
|
||||
} else {
|
||||
@ -442,8 +441,7 @@ ptrace(curp, uap)
|
||||
case PT_WRITE_U:
|
||||
PHOLD(p); /* user had damn well better be incore! */
|
||||
if (p->p_flag & P_INMEM) {
|
||||
p->p_addr->u_kproc.kp_proc = *p;
|
||||
fill_eproc (p, &p->p_addr->u_kproc.kp_eproc);
|
||||
fill_kinfo_proc (p, &p->p_addr->u_kproc);
|
||||
error = ptrace_write_u(p, (vm_offset_t)uap->addr, uap->data);
|
||||
} else {
|
||||
error = EFAULT;
|
||||
|
118
sys/sys/user.h
118
sys/sys/user.h
@ -60,41 +60,93 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
* KERN_PROC subtype ops return arrays of augmented proc structures:
|
||||
* KERN_PROC subtype ops return arrays of selected proc structure entries:
|
||||
*
|
||||
* When adding new fields to this structure, ALWAYS add them at the end
|
||||
* and decrease the size of the spare field by the amount of space that
|
||||
* you are adding. Byte aligned data should be added to the ki_sparestring
|
||||
* space; other entries should be added to the ki_spare space. Always
|
||||
* verify that sizeof(struct kinfo_proc) == KINFO_PROC_SIZE when you are
|
||||
* done. If you change the size of this structure, many programs will stop
|
||||
* working! Once you have added the new field, you will need to add code
|
||||
* to initialize it in two places: kern/kern_proc.c in the function
|
||||
* fill_kinfo_proc and in lib/libkvm/kvm_proc.c in the function kvm_proclist.
|
||||
*/
|
||||
struct kinfo_proc {
|
||||
struct proc kp_proc; /* proc structure */
|
||||
struct eproc {
|
||||
struct proc *e_paddr; /* address of proc */
|
||||
struct session *e_sess; /* session pointer */
|
||||
struct pcred e_pcred; /* process credentials */
|
||||
struct ucred e_ucred; /* current credentials */
|
||||
struct procsig e_procsig; /* shared signal structure */
|
||||
struct vmspace e_vm; /* address space */
|
||||
struct pstats e_stats; /* process stats */
|
||||
pid_t e_ppid; /* parent process id */
|
||||
pid_t e_pgid; /* process group id */
|
||||
short e_jobc; /* job control counter */
|
||||
udev_t e_tdev; /* controlling tty dev */
|
||||
pid_t e_tpgid; /* tty process group id */
|
||||
struct session *e_tsess; /* tty session pointer */
|
||||
#define WMESGLEN 7
|
||||
char e_wmesg[WMESGLEN+1]; /* wchan message */
|
||||
#define MTXNAMELEN 7
|
||||
char e_mtxname[MTXNAMELEN+1];/* blocked mutex */
|
||||
segsz_t e_xsize; /* text size */
|
||||
short e_xrssize; /* text rss */
|
||||
short e_xccount; /* text references */
|
||||
short e_xswrss;
|
||||
long e_flag;
|
||||
#define EPROC_CTTY 0x01 /* controlling tty vnode active */
|
||||
#define EPROC_SLEADER 0x02 /* session leader */
|
||||
char e_login[roundup(MAXLOGNAME, sizeof(long))]; /* setlogin() name */
|
||||
long e_spare[2];
|
||||
} kp_eproc;
|
||||
};
|
||||
void fill_eproc __P((struct proc *, struct eproc *));
|
||||
#define KINFO_PROC_SIZE 640 /* the correct size for kinfo_proc */
|
||||
#define WMESGLEN 8 /* size of returned wchan message */
|
||||
#define MTXNAMELEN 8 /* size of returned mutex name */
|
||||
|
||||
struct kinfo_proc {
|
||||
int ki_structsize; /* size of this structure */
|
||||
struct pargs *ki_args; /* address of command arguments */
|
||||
struct proc *ki_paddr; /* address of proc */
|
||||
struct user *ki_addr; /* kernel virtual addr of u-area */
|
||||
struct vnode *ki_tracep; /* pointer to trace file */
|
||||
struct vnode *ki_textvp; /* pointer to executable file */
|
||||
struct filedesc *ki_fd; /* pointer to open file info */
|
||||
struct vmspace *ki_vmspace; /* pointer to kernel vmspace struct */
|
||||
void *ki_wchan; /* sleep address */
|
||||
pid_t ki_pid; /* Process identifier */
|
||||
pid_t ki_ppid; /* parent process id */
|
||||
pid_t ki_pgid; /* process group id */
|
||||
pid_t ki_tpgid; /* tty process group id */
|
||||
pid_t ki_sid; /* Process session ID */
|
||||
pid_t ki_tsid; /* Terminal session ID */
|
||||
short ki_jobc; /* job control counter */
|
||||
udev_t ki_tdev; /* controlling tty dev */
|
||||
sigset_t ki_siglist; /* Signals arrived but not delivered */
|
||||
sigset_t ki_sigmask; /* Current signal mask */
|
||||
sigset_t ki_sigignore; /* Signals being ignored */
|
||||
sigset_t ki_sigcatch; /* Signals being caught by user */
|
||||
uid_t ki_uid; /* effective user id */
|
||||
uid_t ki_ruid; /* Real user id */
|
||||
uid_t ki_svuid; /* Saved effective user id */
|
||||
gid_t ki_rgid; /* Real group id */
|
||||
gid_t ki_svgid; /* Saved effective group id */
|
||||
short ki_ngroups; /* number of groups */
|
||||
gid_t ki_groups[NGROUPS]; /* groups */
|
||||
vm_size_t ki_size; /* virtual size */
|
||||
segsz_t ki_rssize; /* current resident set size in pages */
|
||||
segsz_t ki_swrss; /* resident set size before last swap */
|
||||
segsz_t ki_tsize; /* text size (pages) XXX */
|
||||
segsz_t ki_dsize; /* data size (pages) XXX */
|
||||
segsz_t ki_ssize; /* stack size (pages) */
|
||||
u_short ki_xstat; /* Exit status for wait & stop signal */
|
||||
u_short ki_acflag; /* Accounting flags */
|
||||
fixpt_t ki_pctcpu; /* %cpu for process during ki_swtime */
|
||||
u_int ki_estcpu; /* Time averaged value of ki_cpticks */
|
||||
u_int ki_slptime; /* Time since last blocked */
|
||||
u_int ki_swtime; /* Time swapped in or out */
|
||||
u_int64_t ki_runtime; /* Real time in microsec */
|
||||
struct timeval ki_start; /* starting time */
|
||||
struct timeval ki_childtime; /* time used by process children */
|
||||
long ki_flag; /* P_* flags */
|
||||
long ki_kiflag; /* KI_* flags (below) */
|
||||
int ki_traceflag; /* Kernel trace points */
|
||||
u_char ki_priority; /* Process priority */
|
||||
u_char ki_usrpri; /* User-priority based on p_cpu */
|
||||
u_char ki_nativepri; /* Priority before propogation */
|
||||
char ki_stat; /* S* process status */
|
||||
char ki_nice; /* Process "nice" value */
|
||||
char ki_lock; /* Process lock (prevent swap) count */
|
||||
char ki_rqindex; /* Run queue index */
|
||||
u_char ki_oncpu; /* Which cpu we are on */
|
||||
u_char ki_lastcpu; /* Last cpu we were on */
|
||||
char ki_comm[MAXCOMLEN+1]; /* command name */
|
||||
char ki_wmesg[WMESGLEN+1]; /* wchan message */
|
||||
char ki_login[MAXLOGNAME+1]; /* setlogin name */
|
||||
char ki_mtxname[MTXNAMELEN+1]; /* mutex name */
|
||||
char ki_sparestrings[102]; /* spare string space */
|
||||
struct rtprio ki_rtprio; /* Realtime priority */
|
||||
struct rusage ki_rusage; /* process rusage statistics */
|
||||
long ki_spare[25]; /* spare constants */
|
||||
};
|
||||
void fill_kinfo_proc __P((struct proc *, struct kinfo_proc *));
|
||||
|
||||
/* ki_sessflag values */
|
||||
#define KI_CTTY 0x00000001 /* controlling tty vnode active */
|
||||
#define KI_SLEADER 0x00000002 /* session leader */
|
||||
#define KI_MTXBLOCK 0x00000004 /* proc blocked on mutex ki_mtxname */
|
||||
|
||||
/*
|
||||
* Per process structure containing data that isn't needed in core
|
||||
|
@ -253,7 +253,7 @@ main(argc, argv)
|
||||
putchar('\n');
|
||||
|
||||
for (plast = &p[cnt]; p < plast; ++p) {
|
||||
if (p->kp_proc.p_stat == SZOMB)
|
||||
if (p->ki_stat == SZOMB)
|
||||
continue;
|
||||
dofiles(p);
|
||||
if (mflg)
|
||||
@ -298,18 +298,16 @@ dofiles(kp)
|
||||
struct file file;
|
||||
struct filedesc0 filed0;
|
||||
#define filed filed0.fd_fd
|
||||
struct proc *p = &kp->kp_proc;
|
||||
struct eproc *ep = &kp->kp_eproc;
|
||||
|
||||
Uname = user_from_uid(ep->e_ucred.cr_uid, 0);
|
||||
Pid = p->p_pid;
|
||||
Comm = p->p_comm;
|
||||
Uname = user_from_uid(kp->ki_uid, 0);
|
||||
Pid = kp->ki_pid;
|
||||
Comm = kp->ki_comm;
|
||||
|
||||
if (p->p_fd == NULL)
|
||||
if (kp->ki_fd == NULL)
|
||||
return;
|
||||
if (!KVM_READ(p->p_fd, &filed0, sizeof (filed0))) {
|
||||
if (!KVM_READ(kp->ki_fd, &filed0, sizeof (filed0))) {
|
||||
dprintf(stderr, "can't read filedesc at %p for pid %d\n",
|
||||
(void *)p->p_fd, Pid);
|
||||
(void *)kp->ki_fd, Pid);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
@ -324,13 +322,13 @@ dofiles(kp)
|
||||
/*
|
||||
* ktrace vnode, if one
|
||||
*/
|
||||
if (p->p_tracep)
|
||||
vtrans(p->p_tracep, TRACE, FREAD|FWRITE);
|
||||
if (kp->ki_tracep)
|
||||
vtrans(kp->ki_tracep, TRACE, FREAD|FWRITE);
|
||||
/*
|
||||
* text vnode, if one
|
||||
*/
|
||||
if (p->p_textvp)
|
||||
vtrans(p->p_textvp, TEXT, FREAD);
|
||||
if (kp->ki_textvp)
|
||||
vtrans(kp->ki_textvp, TEXT, FREAD);
|
||||
/*
|
||||
* open files
|
||||
*/
|
||||
@ -379,24 +377,23 @@ void
|
||||
dommap(kp)
|
||||
struct kinfo_proc *kp;
|
||||
{
|
||||
struct proc *p = &kp->kp_proc;
|
||||
struct vmspace vmspace;
|
||||
vm_map_t map;
|
||||
struct vmspace vmspace;
|
||||
struct vm_map_entry entry;
|
||||
vm_map_entry_t entryp;
|
||||
struct vm_object object;
|
||||
vm_object_t objp;
|
||||
int prot, fflags;
|
||||
|
||||
if (!KVM_READ(p->p_vmspace, &vmspace, sizeof(vmspace))) {
|
||||
dprintf(stderr, "can't read vmspace at %p for pid %d\n",
|
||||
(void *)p->p_vmspace, Pid);
|
||||
if (!KVM_READ(kp->ki_vmspace, &vmspace, sizeof(vmspace))) {
|
||||
dprintf(stderr,
|
||||
"can't read vmspace at %p for pid %d\n",
|
||||
(void *)kp->ki_vmspace, Pid);
|
||||
return;
|
||||
}
|
||||
|
||||
map = &vmspace.vm_map;
|
||||
|
||||
for (entryp = map->header.next; entryp != &p->p_vmspace->vm_map.header;
|
||||
for (entryp = map->header.next; entryp != &vmspace.vm_map.header;
|
||||
entryp = entry.next) {
|
||||
if (!KVM_READ(entryp, &entry, sizeof(entry))) {
|
||||
dprintf(stderr,
|
||||
|
@ -80,15 +80,13 @@ static const char rcsid[] =
|
||||
#include "extern.h"
|
||||
|
||||
static void core __P((int, int, struct kinfo_proc *));
|
||||
static void datadump __P((int, int, struct proc *, u_long, int));
|
||||
static void datadump __P((int, int, struct kinfo_proc *, u_long, int));
|
||||
static void killed __P((int));
|
||||
static void restart_target __P((void));
|
||||
static void usage __P((void)) __dead2;
|
||||
static void userdump __P((int, struct proc *, u_long, int));
|
||||
static void userdump __P((int, struct kinfo_proc *, u_long, int));
|
||||
|
||||
kvm_t *kd;
|
||||
/* XXX undocumented routine, should be in kvm.h? */
|
||||
ssize_t kvm_uread __P((kvm_t *, const struct proc *, u_long, char *, size_t));
|
||||
|
||||
static int data_offset;
|
||||
static pid_t pid;
|
||||
@ -98,7 +96,6 @@ main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
register struct proc *p;
|
||||
struct kinfo_proc *ki = NULL;
|
||||
struct exec exec;
|
||||
int ch, cnt, efd, fd, sflag, uid;
|
||||
@ -164,23 +161,22 @@ main(argc, argv)
|
||||
if (ki == NULL || cnt != 1)
|
||||
errx(1, "%d: not found", pid);
|
||||
|
||||
p = &ki->kp_proc;
|
||||
if (ki->kp_eproc.e_pcred.p_ruid != uid && uid != 0)
|
||||
if (ki->ki_ruid != uid && uid != 0)
|
||||
errx(1, "%d: not owner", pid);
|
||||
|
||||
if (p->p_stat == SZOMB)
|
||||
if (ki->ki_stat == SZOMB)
|
||||
errx(1, "%d: zombie", pid);
|
||||
|
||||
if (p->p_flag & P_WEXIT)
|
||||
if (ki->ki_flag & P_WEXIT)
|
||||
errx(1, "%d: process exiting", pid);
|
||||
if (p->p_flag & P_SYSTEM) /* Swapper or pagedaemon. */
|
||||
if (ki->ki_flag & P_SYSTEM) /* Swapper or pagedaemon. */
|
||||
errx(1, "%d: system process", pid);
|
||||
if (exec.a_text != ptoa(ki->kp_eproc.e_vm.vm_tsize))
|
||||
if (exec.a_text != ptoa(ki->ki_tsize))
|
||||
errx(1, "The executable %s does not belong to"
|
||||
" process %d!\n"
|
||||
"Text segment size (in bytes): executable %ld,"
|
||||
" process %d", binfile, pid, exec.a_text,
|
||||
ptoa(ki->kp_eproc.e_vm.vm_tsize));
|
||||
ptoa(ki->ki_tsize));
|
||||
data_offset = N_DATOFF(exec);
|
||||
} else if (IS_ELF(*(Elf_Ehdr *)&exec)) {
|
||||
is_aout = 0;
|
||||
@ -228,14 +224,13 @@ core(efd, fd, ki)
|
||||
struct user user;
|
||||
char ubytes[ctob(UPAGES)];
|
||||
} uarea;
|
||||
struct proc *p = &ki->kp_proc;
|
||||
int tsize = ki->kp_eproc.e_vm.vm_tsize;
|
||||
int dsize = ki->kp_eproc.e_vm.vm_dsize;
|
||||
int ssize = ki->kp_eproc.e_vm.vm_ssize;
|
||||
int tsize = ki->ki_tsize;
|
||||
int dsize = ki->ki_dsize;
|
||||
int ssize = ki->ki_ssize;
|
||||
int cnt;
|
||||
|
||||
/* Read in user struct */
|
||||
cnt = kvm_read(kd, (u_long)p->p_addr, &uarea, sizeof(uarea));
|
||||
cnt = kvm_read(kd, (u_long)ki->ki_addr, &uarea, sizeof(uarea));
|
||||
if (cnt != sizeof(uarea))
|
||||
errx(1, "read user structure: %s",
|
||||
cnt > 0 ? strerror(EIO) : strerror(errno));
|
||||
@ -253,20 +248,20 @@ core(efd, fd, ki)
|
||||
cnt > 0 ? strerror(EIO) : strerror(errno));
|
||||
|
||||
/* Dump data segment */
|
||||
datadump(efd, fd, p, USRTEXT + ctob(tsize), dsize);
|
||||
datadump(efd, fd, ki, USRTEXT + ctob(tsize), dsize);
|
||||
|
||||
/* Dump stack segment */
|
||||
userdump(fd, p, USRSTACK - ctob(ssize), ssize);
|
||||
userdump(fd, ki, USRSTACK - ctob(ssize), ssize);
|
||||
|
||||
/* Dump machine dependent portions of the core. */
|
||||
md_core(kd, fd, ki);
|
||||
}
|
||||
|
||||
void
|
||||
datadump(efd, fd, p, addr, npage)
|
||||
datadump(efd, fd, kp, addr, npage)
|
||||
register int efd;
|
||||
register int fd;
|
||||
struct proc *p;
|
||||
struct kinfo_proc *kp;
|
||||
register u_long addr;
|
||||
register int npage;
|
||||
{
|
||||
@ -275,7 +270,7 @@ datadump(efd, fd, p, addr, npage)
|
||||
|
||||
delta = data_offset - addr;
|
||||
while (--npage >= 0) {
|
||||
cc = kvm_uread(kd, p, addr, buffer, PAGE_SIZE);
|
||||
cc = kvm_uread(kd, kp, addr, buffer, PAGE_SIZE);
|
||||
if (cc != PAGE_SIZE) {
|
||||
/* Try to read the page from the executable. */
|
||||
if (lseek(efd, (off_t)addr + delta, SEEK_SET) == -1)
|
||||
@ -312,9 +307,9 @@ restart_target()
|
||||
}
|
||||
|
||||
void
|
||||
userdump(fd, p, addr, npage)
|
||||
userdump(fd, kp, addr, npage)
|
||||
register int fd;
|
||||
struct proc *p;
|
||||
struct kinfo_proc *kp;
|
||||
register u_long addr;
|
||||
register int npage;
|
||||
{
|
||||
@ -322,7 +317,7 @@ userdump(fd, p, addr, npage)
|
||||
char buffer[PAGE_SIZE];
|
||||
|
||||
while (--npage >= 0) {
|
||||
cc = kvm_uread(kd, p, addr, buffer, PAGE_SIZE);
|
||||
cc = kvm_uread(kd, kp, addr, buffer, PAGE_SIZE);
|
||||
if (cc != PAGE_SIZE)
|
||||
/* Could be an untouched fill-with-zero page. */
|
||||
bzero(buffer, PAGE_SIZE);
|
||||
|
@ -80,15 +80,13 @@ static const char rcsid[] =
|
||||
#include "extern.h"
|
||||
|
||||
static void core __P((int, int, struct kinfo_proc *));
|
||||
static void datadump __P((int, int, struct proc *, u_long, int));
|
||||
static void datadump __P((int, int, struct kinfo_proc *, u_long, int));
|
||||
static void killed __P((int));
|
||||
static void restart_target __P((void));
|
||||
static void usage __P((void)) __dead2;
|
||||
static void userdump __P((int, struct proc *, u_long, int));
|
||||
static void userdump __P((int, struct kinfo_proc *, u_long, int));
|
||||
|
||||
kvm_t *kd;
|
||||
/* XXX undocumented routine, should be in kvm.h? */
|
||||
ssize_t kvm_uread __P((kvm_t *, const struct proc *, u_long, char *, size_t));
|
||||
|
||||
static int data_offset;
|
||||
static pid_t pid;
|
||||
@ -98,7 +96,6 @@ main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
register struct proc *p;
|
||||
struct kinfo_proc *ki = NULL;
|
||||
struct exec exec;
|
||||
int ch, cnt, efd, fd, sflag, uid;
|
||||
@ -164,23 +161,22 @@ main(argc, argv)
|
||||
if (ki == NULL || cnt != 1)
|
||||
errx(1, "%d: not found", pid);
|
||||
|
||||
p = &ki->kp_proc;
|
||||
if (ki->kp_eproc.e_pcred.p_ruid != uid && uid != 0)
|
||||
if (ki->ki_ruid != uid && uid != 0)
|
||||
errx(1, "%d: not owner", pid);
|
||||
|
||||
if (p->p_stat == SZOMB)
|
||||
if (ki->ki_stat == SZOMB)
|
||||
errx(1, "%d: zombie", pid);
|
||||
|
||||
if (p->p_flag & P_WEXIT)
|
||||
if (ki->ki_flag & P_WEXIT)
|
||||
errx(1, "%d: process exiting", pid);
|
||||
if (p->p_flag & P_SYSTEM) /* Swapper or pagedaemon. */
|
||||
if (ki->ki_flag & P_SYSTEM) /* Swapper or pagedaemon. */
|
||||
errx(1, "%d: system process", pid);
|
||||
if (exec.a_text != ptoa(ki->kp_eproc.e_vm.vm_tsize))
|
||||
if (exec.a_text != ptoa(ki->ki_tsize))
|
||||
errx(1, "The executable %s does not belong to"
|
||||
" process %d!\n"
|
||||
"Text segment size (in bytes): executable %ld,"
|
||||
" process %d", binfile, pid, exec.a_text,
|
||||
ptoa(ki->kp_eproc.e_vm.vm_tsize));
|
||||
ptoa(ki->ki_tsize));
|
||||
data_offset = N_DATOFF(exec);
|
||||
} else if (IS_ELF(*(Elf_Ehdr *)&exec)) {
|
||||
is_aout = 0;
|
||||
@ -228,14 +224,13 @@ core(efd, fd, ki)
|
||||
struct user user;
|
||||
char ubytes[ctob(UPAGES)];
|
||||
} uarea;
|
||||
struct proc *p = &ki->kp_proc;
|
||||
int tsize = ki->kp_eproc.e_vm.vm_tsize;
|
||||
int dsize = ki->kp_eproc.e_vm.vm_dsize;
|
||||
int ssize = ki->kp_eproc.e_vm.vm_ssize;
|
||||
int tsize = ki->ki_tsize;
|
||||
int dsize = ki->ki_dsize;
|
||||
int ssize = ki->ki_ssize;
|
||||
int cnt;
|
||||
|
||||
/* Read in user struct */
|
||||
cnt = kvm_read(kd, (u_long)p->p_addr, &uarea, sizeof(uarea));
|
||||
cnt = kvm_read(kd, (u_long)ki->ki_addr, &uarea, sizeof(uarea));
|
||||
if (cnt != sizeof(uarea))
|
||||
errx(1, "read user structure: %s",
|
||||
cnt > 0 ? strerror(EIO) : strerror(errno));
|
||||
@ -253,20 +248,20 @@ core(efd, fd, ki)
|
||||
cnt > 0 ? strerror(EIO) : strerror(errno));
|
||||
|
||||
/* Dump data segment */
|
||||
datadump(efd, fd, p, USRTEXT + ctob(tsize), dsize);
|
||||
datadump(efd, fd, ki, USRTEXT + ctob(tsize), dsize);
|
||||
|
||||
/* Dump stack segment */
|
||||
userdump(fd, p, USRSTACK - ctob(ssize), ssize);
|
||||
userdump(fd, ki, USRSTACK - ctob(ssize), ssize);
|
||||
|
||||
/* Dump machine dependent portions of the core. */
|
||||
md_core(kd, fd, ki);
|
||||
}
|
||||
|
||||
void
|
||||
datadump(efd, fd, p, addr, npage)
|
||||
datadump(efd, fd, kp, addr, npage)
|
||||
register int efd;
|
||||
register int fd;
|
||||
struct proc *p;
|
||||
struct kinfo_proc *kp;
|
||||
register u_long addr;
|
||||
register int npage;
|
||||
{
|
||||
@ -275,7 +270,7 @@ datadump(efd, fd, p, addr, npage)
|
||||
|
||||
delta = data_offset - addr;
|
||||
while (--npage >= 0) {
|
||||
cc = kvm_uread(kd, p, addr, buffer, PAGE_SIZE);
|
||||
cc = kvm_uread(kd, kp, addr, buffer, PAGE_SIZE);
|
||||
if (cc != PAGE_SIZE) {
|
||||
/* Try to read the page from the executable. */
|
||||
if (lseek(efd, (off_t)addr + delta, SEEK_SET) == -1)
|
||||
@ -312,9 +307,9 @@ restart_target()
|
||||
}
|
||||
|
||||
void
|
||||
userdump(fd, p, addr, npage)
|
||||
userdump(fd, kp, addr, npage)
|
||||
register int fd;
|
||||
struct proc *p;
|
||||
struct kinfo_proc *kp;
|
||||
register u_long addr;
|
||||
register int npage;
|
||||
{
|
||||
@ -322,7 +317,7 @@ userdump(fd, p, addr, npage)
|
||||
char buffer[PAGE_SIZE];
|
||||
|
||||
while (--npage >= 0) {
|
||||
cc = kvm_uread(kd, p, addr, buffer, PAGE_SIZE);
|
||||
cc = kvm_uread(kd, kp, addr, buffer, PAGE_SIZE);
|
||||
if (cc != PAGE_SIZE)
|
||||
/* Could be an untouched fill-with-zero page. */
|
||||
bzero(buffer, PAGE_SIZE);
|
||||
|
@ -44,7 +44,6 @@ static char sccsid[] = "@(#)pigs.c 8.2 (Berkeley) 9/23/93";
|
||||
#include <sys/param.h>
|
||||
#include <sys/dkstat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
@ -91,7 +90,6 @@ void
|
||||
showpigs()
|
||||
{
|
||||
register int i, j, y, k;
|
||||
struct eproc *ep;
|
||||
float total;
|
||||
int factor;
|
||||
char *uname, *pname, pidname[30];
|
||||
@ -120,9 +118,9 @@ showpigs()
|
||||
pname = "<idle>";
|
||||
}
|
||||
else {
|
||||
ep = &pt[k].pt_kp->kp_eproc;
|
||||
uname = (char *)user_from_uid(ep->e_ucred.cr_uid, 0);
|
||||
pname = pt[k].pt_kp->kp_proc.p_comm;
|
||||
uname = (char *)
|
||||
user_from_uid(pt[k].pt_kp->ki_uid, 0);
|
||||
pname = pt[k].pt_kp->ki_comm;
|
||||
}
|
||||
wmove(wnd, y, 0);
|
||||
wclrtoeol(wnd);
|
||||
@ -174,7 +172,6 @@ fetchpigs()
|
||||
{
|
||||
register int i;
|
||||
register float time;
|
||||
register struct proc *pp;
|
||||
register float *pctp;
|
||||
struct kinfo_proc *kpp;
|
||||
long ctime[CPUSTATES];
|
||||
@ -203,13 +200,12 @@ fetchpigs()
|
||||
*/
|
||||
for (i = 0; i < nproc; i++) {
|
||||
pt[i].pt_kp = &kpp[i];
|
||||
pp = &kpp[i].kp_proc;
|
||||
pctp = &pt[i].pt_pctcpu;
|
||||
time = pp->p_swtime;
|
||||
if (time == 0 || (pp->p_flag & P_INMEM) == 0)
|
||||
time = kpp[i].ki_swtime;
|
||||
if (time == 0 || (kpp[i].ki_flag & P_INMEM) == 0)
|
||||
*pctp = 0;
|
||||
else
|
||||
*pctp = ((double) pp->p_pctcpu /
|
||||
*pctp = ((double) kpp[i].ki_pctcpu /
|
||||
fscale) / (1.0 - exp(time * lccpu));
|
||||
}
|
||||
/*
|
||||
|
@ -75,16 +75,12 @@ struct handle
|
||||
/* declarations for load_avg */
|
||||
#include "loadavg.h"
|
||||
|
||||
#define PP(pp, field) ((pp)->kp_proc . field)
|
||||
#define EP(pp, field) ((pp)->kp_eproc . field)
|
||||
#define VP(pp, field) ((pp)->kp_eproc.e_vm . field)
|
||||
|
||||
/* define what weighted cpu is. */
|
||||
#define weighted_cpu(pct, pp) (PP((pp), p_swtime) == 0 ? 0.0 : \
|
||||
((pct) / (1.0 - exp(PP((pp), p_swtime) * logcpu))))
|
||||
#define weighted_cpu(pct, pp) ((pp)->ki_swtime == 0 ? 0.0 : \
|
||||
((pct) / (1.0 - exp((pp)->ki_swtime * logcpu))))
|
||||
|
||||
/* what we consider to be process size: */
|
||||
#define PROCSIZE(pp) (VP((pp), vm_map.size) / 1024)
|
||||
#define PROCSIZE(pp) ((pp)->ki_size / 1024)
|
||||
|
||||
/* definitions for indices in the nlist array */
|
||||
|
||||
@ -501,16 +497,16 @@ int (*compare)();
|
||||
* status field. Processes with P_SYSTEM set are system
|
||||
* processes---these get ignored unless show_sysprocs is set.
|
||||
*/
|
||||
if (PP(pp, p_stat) != 0 &&
|
||||
(show_self != PP(pp, p_pid)) &&
|
||||
(show_system || ((PP(pp, p_flag) & P_SYSTEM) == 0)))
|
||||
if (pp->ki_stat != 0 &&
|
||||
(show_self != pp->ki_pid) &&
|
||||
(show_system || ((pp->ki_flag & P_SYSTEM) == 0)))
|
||||
{
|
||||
total_procs++;
|
||||
process_states[(unsigned char) PP(pp, p_stat)]++;
|
||||
if ((PP(pp, p_stat) != SZOMB) &&
|
||||
(show_idle || (PP(pp, p_pctcpu) != 0) ||
|
||||
(PP(pp, p_stat) == SRUN)) &&
|
||||
(!show_uid || EP(pp, e_pcred.p_ruid) == (uid_t)sel->uid))
|
||||
process_states[(unsigned char) pp->ki_stat]++;
|
||||
if ((pp->ki_stat != SZOMB) &&
|
||||
(show_idle || (pp->ki_pctcpu != 0) ||
|
||||
(pp->ki_stat == SRUN)) &&
|
||||
(!show_uid || pp->ki_ruid == (uid_t)sel->uid))
|
||||
{
|
||||
*prefp++ = pp;
|
||||
active_procs++;
|
||||
@ -555,12 +551,12 @@ char *(*get_userid)();
|
||||
hp->remaining--;
|
||||
|
||||
/* get the process's command name */
|
||||
if ((PP(pp, p_flag) & P_INMEM) == 0) {
|
||||
if ((pp->ki_flag & P_INMEM) == 0) {
|
||||
/*
|
||||
* Print swapped processes as <pname>
|
||||
*/
|
||||
char *comm = PP(pp, p_comm);
|
||||
#define COMSIZ sizeof(PP(pp, p_comm))
|
||||
char *comm = pp->ki_comm;
|
||||
#define COMSIZ sizeof(pp->ki_comm)
|
||||
char buf[COMSIZ];
|
||||
(void) strncpy(buf, comm, COMSIZ);
|
||||
comm[0] = '<';
|
||||
@ -575,28 +571,28 @@ char *(*get_userid)();
|
||||
* time includes the interrupt time although that is not wanted here.
|
||||
* ps(1) is similarly sloppy.
|
||||
*/
|
||||
cputime = (PP(pp, p_runtime) + 500000) / 1000000;
|
||||
cputime = (pp->ki_runtime + 500000) / 1000000;
|
||||
|
||||
/* calculate the base for cpu percentages */
|
||||
pct = pctdouble(PP(pp, p_pctcpu));
|
||||
pct = pctdouble(pp->ki_pctcpu);
|
||||
|
||||
/* generate "STATE" field */
|
||||
switch (state = PP(pp, p_stat)) {
|
||||
switch (state = pp->ki_stat) {
|
||||
case SRUN:
|
||||
if (smpmode && PP(pp, p_oncpu) != 0xff)
|
||||
sprintf(status, "CPU%d", PP(pp, p_oncpu));
|
||||
if (smpmode && pp->ki_oncpu != 0xff)
|
||||
sprintf(status, "CPU%d", pp->ki_oncpu);
|
||||
else
|
||||
strcpy(status, "RUN");
|
||||
break;
|
||||
case SMTX:
|
||||
if (PP(pp, p_mtxname) != NULL) {
|
||||
sprintf(status, "*%.6s", EP(pp, e_mtxname));
|
||||
if (pp->ki_kiflag & KI_MTXBLOCK) {
|
||||
sprintf(status, "*%.6s", pp->ki_mtxname);
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case SSLEEP:
|
||||
if (PP(pp, p_wmesg) != NULL) {
|
||||
sprintf(status, "%.6s", EP(pp, e_wmesg));
|
||||
if (pp->ki_wmesg != NULL) {
|
||||
sprintf(status, "%.6s", pp->ki_wmesg);
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
@ -613,32 +609,32 @@ char *(*get_userid)();
|
||||
/* format this entry */
|
||||
sprintf(fmt,
|
||||
smpmode ? smp_Proc_format : up_Proc_format,
|
||||
PP(pp, p_pid),
|
||||
pp->ki_pid,
|
||||
namelength, namelength,
|
||||
(*get_userid)(EP(pp, e_pcred.p_ruid)),
|
||||
PP(pp, p_priority) - PZERO,
|
||||
(*get_userid)(pp->ki_ruid),
|
||||
pp->ki_priority - PZERO,
|
||||
|
||||
/*
|
||||
* normal time -> nice value -20 - +20
|
||||
* real time 0 - 31 -> nice value -52 - -21
|
||||
* idle time 0 - 31 -> nice value +21 - +52
|
||||
*/
|
||||
(PP(pp, p_rtprio.type) == RTP_PRIO_NORMAL ?
|
||||
PP(pp, p_nice) - NZERO :
|
||||
(RTP_PRIO_IS_REALTIME(PP(pp, p_rtprio.type)) ?
|
||||
(PRIO_MIN - 1 - RTP_PRIO_MAX + PP(pp, p_rtprio.prio)) :
|
||||
(PRIO_MAX + 1 + PP(pp, p_rtprio.prio)))),
|
||||
(pp->ki_rtprio.type == RTP_PRIO_NORMAL ?
|
||||
pp->ki_nice - NZERO :
|
||||
(RTP_PRIO_IS_REALTIME(pp->ki_rtprio.type) ?
|
||||
(PRIO_MIN - 1 - RTP_PRIO_MAX + pp->ki_rtprio.prio) :
|
||||
(PRIO_MAX + 1 + pp->ki_rtprio.prio))),
|
||||
format_k2(PROCSIZE(pp)),
|
||||
format_k2(pagetok(VP(pp, vm_rssize))),
|
||||
format_k2(pagetok(pp->ki_rssize)),
|
||||
status,
|
||||
smpmode ? PP(pp, p_lastcpu) : 0,
|
||||
smpmode ? pp->ki_lastcpu : 0,
|
||||
format_time(cputime),
|
||||
100.0 * weighted_cpu(pct, pp),
|
||||
100.0 * pct,
|
||||
screen_width > cmdlengthdelta ?
|
||||
screen_width - cmdlengthdelta :
|
||||
0,
|
||||
printable(PP(pp, p_comm)));
|
||||
printable(pp->ki_comm));
|
||||
|
||||
/* return the result */
|
||||
return(fmt);
|
||||
@ -741,22 +737,22 @@ static unsigned char sorted_state[] =
|
||||
|
||||
|
||||
#define ORDERKEY_PCTCPU \
|
||||
if (lresult = (long) PP(p2, p_pctcpu) - (long) PP(p1, p_pctcpu), \
|
||||
if (lresult = (long) p2->ki_pctcpu - (long) p1->ki_pctcpu, \
|
||||
(result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0)
|
||||
|
||||
#define ORDERKEY_CPTICKS \
|
||||
if ((result = PP(p2, p_runtime) > PP(p1, p_runtime) ? 1 : \
|
||||
PP(p2, p_runtime) < PP(p1, p_runtime) ? -1 : 0) == 0)
|
||||
if ((result = p2->ki_runtime > p1->ki_runtime ? 1 : \
|
||||
p2->ki_runtime < p1->ki_runtime ? -1 : 0) == 0)
|
||||
|
||||
#define ORDERKEY_STATE \
|
||||
if ((result = sorted_state[(unsigned char) PP(p2, p_stat)] - \
|
||||
sorted_state[(unsigned char) PP(p1, p_stat)]) == 0)
|
||||
if ((result = sorted_state[(unsigned char) p2->ki_stat] - \
|
||||
sorted_state[(unsigned char) p1->ki_stat]) == 0)
|
||||
|
||||
#define ORDERKEY_PRIO \
|
||||
if ((result = PP(p2, p_priority) - PP(p1, p_priority)) == 0)
|
||||
if ((result = p2->ki_priority - p1->ki_priority) == 0)
|
||||
|
||||
#define ORDERKEY_RSSIZE \
|
||||
if ((result = VP(p2, vm_rssize) - VP(p1, vm_rssize)) == 0)
|
||||
if ((result = p2->ki_rssize - p1->ki_rssize) == 0)
|
||||
|
||||
#define ORDERKEY_MEM \
|
||||
if ( (result = PROCSIZE(p2) - PROCSIZE(p1)) == 0 )
|
||||
@ -948,9 +944,9 @@ int pid;
|
||||
while (--cnt >= 0)
|
||||
{
|
||||
pp = *prefp++;
|
||||
if (PP(pp, p_pid) == (pid_t)pid)
|
||||
if (pp->ki_pid == (pid_t)pid)
|
||||
{
|
||||
return((int)EP(pp, e_pcred.p_ruid));
|
||||
return((int)pp->ki_ruid);
|
||||
}
|
||||
}
|
||||
return(-1);
|
||||
|
@ -31,9 +31,11 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)extern.h 8.1 (Berkeley) 6/6/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
struct proc;
|
||||
|
||||
struct kinfo_proc;
|
||||
void pr_attime __P((time_t *, time_t *));
|
||||
int pr_idle __P((time_t));
|
||||
int proc_compare __P((struct proc *, struct proc *));
|
||||
int proc_compare __P((struct kinfo_proc *, struct kinfo_proc *));
|
||||
|
@ -32,12 +32,16 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)proc_compare.c 8.2 (Berkeley) 9/23/93";
|
||||
#endif
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
@ -60,7 +64,7 @@ static char sccsid[] = "@(#)proc_compare.c 8.2 (Berkeley) 9/23/93";
|
||||
* TODO - consider whether pctcpu should be used.
|
||||
*/
|
||||
|
||||
#define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
|
||||
#define ISRUN(p) (((p)->ki_stat == SRUN) || ((p)->ki_stat == SIDL))
|
||||
#define TESTAB(a, b) ((a)<<1 | (b))
|
||||
#define ONLYA 2
|
||||
#define ONLYB 1
|
||||
@ -68,7 +72,7 @@ static char sccsid[] = "@(#)proc_compare.c 8.2 (Berkeley) 9/23/93";
|
||||
|
||||
int
|
||||
proc_compare(p1, p2)
|
||||
register struct proc *p1, *p2;
|
||||
struct kinfo_proc *p1, *p2;
|
||||
{
|
||||
|
||||
if (p1 == NULL)
|
||||
@ -85,36 +89,36 @@ proc_compare(p1, p2)
|
||||
/*
|
||||
* tie - favor one with highest recent cpu utilization
|
||||
*/
|
||||
if (p2->p_estcpu > p1->p_estcpu)
|
||||
if (p2->ki_estcpu > p1->ki_estcpu)
|
||||
return (1);
|
||||
if (p1->p_estcpu > p2->p_estcpu)
|
||||
if (p1->ki_estcpu > p2->ki_estcpu)
|
||||
return (0);
|
||||
return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
|
||||
return (p2->ki_pid > p1->ki_pid); /* tie - return highest pid */
|
||||
}
|
||||
/*
|
||||
* weed out zombies
|
||||
*/
|
||||
switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
|
||||
switch (TESTAB(p1->ki_stat == SZOMB, p2->ki_stat == SZOMB)) {
|
||||
case ONLYA:
|
||||
return (1);
|
||||
case ONLYB:
|
||||
return (0);
|
||||
case BOTH:
|
||||
return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
|
||||
return (p2->ki_pid > p1->ki_pid); /* tie - return highest pid */
|
||||
}
|
||||
/*
|
||||
* pick the one with the smallest sleep time
|
||||
*/
|
||||
if (p2->p_slptime > p1->p_slptime)
|
||||
if (p2->ki_slptime > p1->ki_slptime)
|
||||
return (0);
|
||||
if (p1->p_slptime > p2->p_slptime)
|
||||
if (p1->ki_slptime > p2->ki_slptime)
|
||||
return (1);
|
||||
/*
|
||||
* favor one sleeping in a non-interruptible sleep
|
||||
*/
|
||||
if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0)
|
||||
if (p1->ki_flag & P_SINTR && (p2->ki_flag & P_SINTR) == 0)
|
||||
return (1);
|
||||
if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0)
|
||||
if (p2->ki_flag & P_SINTR && (p1->ki_flag & P_SINTR) == 0)
|
||||
return (0);
|
||||
return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
|
||||
return (p2->ki_pid > p1->ki_pid); /* tie - return highest pid */
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ struct entry {
|
||||
struct kinfo_proc *dkp; /* debug option proc list */
|
||||
} *ep, *ehead = NULL, **nextp = &ehead;
|
||||
|
||||
#define debugproc(p) *((struct kinfo_proc **)&(p)->kp_eproc.e_spare[0])
|
||||
#define debugproc(p) *((struct kinfo_proc **)&(p)->ki_spare[0])
|
||||
|
||||
static void pr_header __P((time_t *, int));
|
||||
static struct stat *ttystat __P((char *, int));
|
||||
@ -273,27 +273,23 @@ main(argc, argv)
|
||||
if ((kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nentries)) == NULL)
|
||||
err(1, "%s", kvm_geterr(kd));
|
||||
for (i = 0; i < nentries; i++, kp++) {
|
||||
struct proc *pr = &kp->kp_proc;
|
||||
struct eproc *e;
|
||||
|
||||
if (pr->p_stat == SIDL || pr->p_stat == SZOMB)
|
||||
if (kp->ki_stat == SIDL || kp->ki_stat == SZOMB)
|
||||
continue;
|
||||
e = &kp->kp_eproc;
|
||||
for (ep = ehead; ep != NULL; ep = ep->next) {
|
||||
if (ep->tdev == e->e_tdev) {
|
||||
if (ep->tdev == kp->ki_tdev) {
|
||||
/*
|
||||
* proc is associated with this terminal
|
||||
*/
|
||||
if (ep->kp == NULL && e->e_pgid == e->e_tpgid) {
|
||||
if (ep->kp == NULL && kp->ki_pgid == kp->ki_tpgid) {
|
||||
/*
|
||||
* Proc is 'most interesting'
|
||||
*/
|
||||
if (proc_compare(&ep->kp->kp_proc, pr))
|
||||
if (proc_compare(ep->kp, kp))
|
||||
ep->kp = kp;
|
||||
}
|
||||
/*
|
||||
* Proc debug option info; add to debug
|
||||
* list using kinfo_proc kp_eproc.e_spare
|
||||
* list using kinfo_proc ki_spare[0]
|
||||
* as next pointer; ptr to ptr avoids the
|
||||
* ptr = long assumption.
|
||||
*/
|
||||
@ -318,7 +314,7 @@ main(argc, argv)
|
||||
continue;
|
||||
}
|
||||
ep->args = fmt_argv(kvm_getargv(kd, ep->kp, argwidth),
|
||||
ep->kp->kp_proc.p_comm, MAXCOMLEN);
|
||||
ep->kp->ki_comm, MAXCOMLEN);
|
||||
if (ep->args == NULL)
|
||||
err(1, NULL);
|
||||
}
|
||||
@ -389,11 +385,11 @@ main(argc, argv)
|
||||
char *ptr;
|
||||
|
||||
ptr = fmt_argv(kvm_getargv(kd, dkp, argwidth),
|
||||
dkp->kp_proc.p_comm, MAXCOMLEN);
|
||||
dkp->ki_comm, MAXCOMLEN);
|
||||
if (ptr == NULL)
|
||||
ptr = "-";
|
||||
(void)printf("\t\t%-9d %s\n",
|
||||
dkp->kp_proc.p_pid, ptr);
|
||||
dkp->ki_pid, ptr);
|
||||
}
|
||||
}
|
||||
(void)printf("%-*.*s %-*.*s %-*.*s ",
|
||||
|
Loading…
Reference in New Issue
Block a user