Changeset View
Standalone View
sys/kern/tty_info.c
Show First 20 Lines • Show All 233 Lines • ▼ Show 20 Lines | if (tp != NULL && !KERNEL_PANICKED()) { | ||||
if (rc != 0) | if (rc != 0) | ||||
return (-ENXIO); | return (-ENXIO); | ||||
return (len); | return (len); | ||||
} | } | ||||
return (-ENXIO); | return (-ENXIO); | ||||
} | } | ||||
#ifdef STACK | #ifdef STACK | ||||
static bool tty_info_kstacks = true; | static int tty_info_kstacks = STACK_SBUF_FMT_COMPACT; | ||||
SYSCTL_BOOL(_kern, OID_AUTO, tty_info_kstacks, CTLFLAG_RWTUN, | |||||
&tty_info_kstacks, 0, | static int | ||||
"Enable printing kernel stack(9) traces on ^T (tty info)"); | sysctl_tty_info_kstacks(SYSCTL_HANDLER_ARGS) | ||||
{ | |||||
enum stack_sbuf_fmt val; | |||||
int error; | |||||
val = tty_info_kstacks; | |||||
error = sysctl_handle_int(oidp, &val, 0, req); | |||||
if (error != 0 || req->newptr == NULL) | |||||
return (error); | |||||
cem: Don’t we have a range-limited sysctl mechanism already? | |||||
Done Inline ActionsNot that I know of, but if checking for a current value isn't welcomed it can be squashed to bare SYSCTL_INT. kaktus: Not that I know of, but if checking for a current value isn't welcomed it can be squashed to… | |||||
Done Inline Actionss/current/correct/ kaktus: s/current/correct/ | |||||
Not Done Inline Actionsdev/random/randomdev.h RANDOM_CHECK_UINT is probably what I was thinking of. I don't think it's quite what we'd want here (we just an upper limit encoded in arg2). I think it might be nice to eventually have a range-limited sysctl mechanism, but of course it is orthogonal to this change. cem: dev/random/randomdev.h `RANDOM_CHECK_UINT` is probably what I was thinking of. I don't think… | |||||
switch (val) { | |||||
case STACK_SBUF_FMT_NONE: | |||||
case STACK_SBUF_FMT_LONG: | |||||
case STACK_SBUF_FMT_COMPACT: | |||||
tty_info_kstacks = val; | |||||
break; | |||||
default: | |||||
__assert_unreachable(); | |||||
} | |||||
return (error); | |||||
} | |||||
SYSCTL_PROC(_kern, OID_AUTO, tty_info_kstacks, | |||||
CTLFLAG_RWTUN | CTLFLAG_MPSAFE | CTLTYPE_INT, NULL, 0, | |||||
sysctl_tty_info_kstacks, "I", | |||||
"Adjust format of kernel stack(9) traces on ^T (tty info): " | |||||
"0 - disabled; 1 - long; 2 - compact"); | |||||
Done Inline ActionsI believe it should be enough in most cases even for developers? kaktus: I believe it should be enough in most cases even for developers? | |||||
Not Done Inline ActionsThey print similar information, but I find the one-per-line format much more legible. cem: They print similar information, but I find the one-per-line format much more legible. | |||||
Not Done Inline ActionsShould the additional functionality be separate from the change in default? cem: Should the additional functionality be separate from the change in default? | |||||
#endif | #endif | ||||
/* | /* | ||||
* 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; | ||||
#ifdef STACK | #ifdef STACK | ||||
struct stack stack; | struct stack stack; | ||||
int sterr; | int sterr, kstacks_val; | ||||
bool print_kstacks; | |||||
#endif | #endif | ||||
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; | ||||
pid_t pid; | pid_t pid; | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | #endif | ||||
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; | ||||
#ifdef STACK | #ifdef STACK | ||||
if (tty_info_kstacks) { | kstacks_val = atomic_load_int(&tty_info_kstacks); | ||||
print_kstacks = (kstacks_val != STACK_SBUF_FMT_NONE); | |||||
if (print_kstacks) { | |||||
Not Done Inline ActionsProbably want to load the value of tty_info_kstacks once, as the sysctl could change it between here and the use below, causing use-of-uninitialized-stack-values. cem: Probably want to load the value of `tty_info_kstacks` once, as the sysctl could change it… | |||||
Done Inline ActionsGood catch, will fix. kaktus: Good catch, will fix. | |||||
Not Done Inline Actionsfor safety this should be atomic_load_int(&tty_info_kstacks) to make sure the compiler never reloads this, looks good otherwise mjg: for safety this should be atomic_load_int(&tty_info_kstacks) to make sure the compiler never… | |||||
if (TD_IS_SWAPPED(td)) | if (TD_IS_SWAPPED(td)) | ||||
Not Done Inline Actionsprint_kstacks = (kstacks_val != STACK_SBUF_FMT_NONE); ? cem: `print_kstacks = (kstacks_val != STACK_SBUF_FMT_NONE);` ? | |||||
sterr = ENOENT; | sterr = ENOENT; | ||||
else | else | ||||
sterr = stack_save_td(&stack, td); | sterr = stack_save_td(&stack, td); | ||||
} | } | ||||
#endif | #endif | ||||
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; | ||||
Show All 11 Lines | 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); | ||||
#ifdef STACK | #ifdef STACK | ||||
if (tty_info_kstacks && sterr == 0) | if (print_kstacks && sterr == 0) | ||||
stack_sbuf_print_flags(&sb, &stack, M_NOWAIT); | stack_sbuf_print_flags(&sb, &stack, M_NOWAIT, kstacks_val); | ||||
#endif | #endif | ||||
out: | out: | ||||
sbuf_finish(&sb); | sbuf_finish(&sb); | ||||
sbuf_delete(&sb); | sbuf_delete(&sb); | ||||
} | } |
Don’t we have a range-limited sysctl mechanism already?