Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/tty_info.c
Show First 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/cons.h> | #include <sys/cons.h> | ||||
#include <sys/kdb.h> | #include <sys/kdb.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/malloc.h> | |||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/resourcevar.h> | #include <sys/resourcevar.h> | ||||
#include <sys/sbuf.h> | #include <sys/sbuf.h> | ||||
#include <sys/sched.h> | #include <sys/sched.h> | ||||
#include <sys/stack.h> | |||||
#include <sys/sysctl.h> | |||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/tty.h> | #include <sys/tty.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/pmap.h> | #include <vm/pmap.h> | ||||
#include <vm/vm_map.h> | #include <vm/vm_map.h> | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 163 Lines • ▼ Show 20 Lines | if (tp != NULL && panicstr == NULL) { | ||||
rc = tty_putstrn(tp, d, len); | rc = tty_putstrn(tp, d, len); | ||||
if (rc != 0) | if (rc != 0) | ||||
return (-ENXIO); | return (-ENXIO); | ||||
return (len); | return (len); | ||||
} | } | ||||
return (-ENXIO); | return (-ENXIO); | ||||
} | } | ||||
static bool tty_info_kstacks = false; | |||||
SYSCTL_BOOL(_kern, OID_AUTO, tty_info_kstacks, CTLFLAG_RWTUN, | |||||
&tty_info_kstacks, 0, | |||||
"Enable printing kernel stack(9) traces on ^T (tty info)"); | |||||
/* | /* | ||||
* Report on state of foreground process group. | * Report on state of foreground process group. | ||||
*/ | */ | ||||
void | void | ||||
tty_info(struct tty *tp) | tty_info(struct tty *tp) | ||||
{ | { | ||||
struct timeval rtime, utime, stime; | struct timeval rtime, utime, stime; | ||||
struct stack stack; | |||||
struct proc *p, *ppick; | struct proc *p, *ppick; | ||||
struct thread *td, *tdpick; | struct thread *td, *tdpick; | ||||
const char *stateprefix, *state; | const char *stateprefix, *state; | ||||
struct sbuf sb; | struct sbuf sb; | ||||
long rss; | long rss; | ||||
int load, pctcpu; | int load, pctcpu, sterr; | ||||
pid_t pid; | pid_t pid; | ||||
char comm[MAXCOMLEN + 1]; | char comm[MAXCOMLEN + 1]; | ||||
struct rusage ru; | struct rusage ru; | ||||
tty_lock_assert(tp, MA_OWNED); | tty_lock_assert(tp, MA_OWNED); | ||||
if (tty_checkoutq(tp) == 0) | if (tty_checkoutq(tp) == 0) | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | else if (TD_IS_SLEEPING(td)) { | ||||
state = "suspended"; | state = "suspended"; | ||||
else if (TD_AWAITING_INTR(td)) | else if (TD_AWAITING_INTR(td)) | ||||
state = "intrwait"; | state = "intrwait"; | ||||
else if (p->p_state == PRS_ZOMBIE) | else if (p->p_state == PRS_ZOMBIE) | ||||
state = "zombie"; | state = "zombie"; | ||||
else | else | ||||
state = "unknown"; | state = "unknown"; | ||||
pctcpu = (sched_pctcpu(td) * 10000 + FSCALE / 2) >> FSHIFT; | pctcpu = (sched_pctcpu(td) * 10000 + FSCALE / 2) >> FSHIFT; | ||||
if (tty_info_kstacks) { | |||||
stack_zero(&stack); | |||||
if (TD_IS_SWAPPED(td) || TD_IS_RUNNING(td)) | |||||
sterr = stack_save_td_running(&stack, td); | |||||
else { | |||||
stack_save_td(&stack, td); | |||||
sterr = 0; | |||||
} | |||||
} | |||||
thread_unlock(td); | thread_unlock(td); | ||||
if (p->p_state == PRS_NEW || p->p_state == PRS_ZOMBIE) | if (p->p_state == PRS_NEW || p->p_state == PRS_ZOMBIE) | ||||
rss = 0; | rss = 0; | ||||
else | else | ||||
rss = pgtok(vmspace_resident_count(p->p_vmspace)); | rss = pgtok(vmspace_resident_count(p->p_vmspace)); | ||||
microuptime(&rtime); | microuptime(&rtime); | ||||
timevalsub(&rtime, &p->p_stats->p_start); | timevalsub(&rtime, &p->p_stats->p_start); | ||||
rufetchcalc(p, &ru, &utime, &stime); | rufetchcalc(p, &ru, &utime, &stime); | ||||
pid = p->p_pid; | pid = p->p_pid; | ||||
strlcpy(comm, p->p_comm, sizeof comm); | strlcpy(comm, p->p_comm, sizeof comm); | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
/* Print command, pid, state, rtime, utime, stime, %cpu, and rss. */ | /* Print command, pid, state, rtime, utime, stime, %cpu, and rss. */ | ||||
sbuf_printf(&sb, | sbuf_printf(&sb, | ||||
" cmd: %s %d [%s%s] %ld.%02ldr %ld.%02ldu %ld.%02lds %d%% %ldk\n", | " cmd: %s %d [%s%s] %ld.%02ldr %ld.%02ldu %ld.%02lds %d%% %ldk\n", | ||||
comm, pid, stateprefix, state, | comm, pid, stateprefix, state, | ||||
(long)rtime.tv_sec, rtime.tv_usec / 10000, | (long)rtime.tv_sec, rtime.tv_usec / 10000, | ||||
(long)utime.tv_sec, utime.tv_usec / 10000, | (long)utime.tv_sec, utime.tv_usec / 10000, | ||||
(long)stime.tv_sec, stime.tv_usec / 10000, | (long)stime.tv_sec, stime.tv_usec / 10000, | ||||
pctcpu / 100, rss); | pctcpu / 100, rss); | ||||
if (tty_info_kstacks && sterr == 0) | |||||
stack_sbuf_print_flags(&sb, &stack, M_NOWAIT); | |||||
out: | out: | ||||
sbuf_finish(&sb); | sbuf_finish(&sb); | ||||
sbuf_delete(&sb); | sbuf_delete(&sb); | ||||
} | } |