diff options
author | markj <markj@FreeBSD.org> | 2015-09-11 03:54:37 +0000 |
---|---|---|
committer | markj <markj@FreeBSD.org> | 2015-09-11 03:54:37 +0000 |
commit | e8967c8bd970aade474f6148fbbe4b0e6183751a (patch) | |
tree | 28426773e296f84e10d3d95e2a1489974f368b93 /sys/amd64 | |
parent | b30bc0e211f2c169b84e83127d7d57de24fb688d (diff) | |
download | FreeBSD-src-e8967c8bd970aade474f6148fbbe4b0e6183751a.zip FreeBSD-src-e8967c8bd970aade474f6148fbbe4b0e6183751a.tar.gz |
Add stack_save_td_running(), a function to trace the kernel stack of a
running thread.
It is currently implemented only on amd64 and i386; on these
architectures, it is implemented by raising an NMI on the CPU on which
the target thread is currently running. Unlike stack_save_td(), it may
fail, for example if the thread is running in user mode.
This change also modifies the kern.proc.kstack sysctl to use this function,
so that stacks of running threads are shown in the output of "procstat -kk".
This is handy for debugging threads that are stuck in a busy loop.
Reviewed by: bdrewery, jhb, kib
Sponsored by: EMC / Isilon Storage Division
Differential Revision: https://reviews.freebsd.org/D3256
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/trap.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 3bf63c3..776f90c 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include "opt_hwpmc_hooks.h" #include "opt_isa.h" #include "opt_kdb.h" +#include "opt_stack.h" #include <sys/param.h> #include <sys/bus.h> @@ -91,6 +92,7 @@ PMC_SOFT_DEFINE( , , page_fault, write); #ifdef SMP #include <machine/smp.h> #endif +#include <machine/stack.h> #include <machine/tss.h> #ifdef KDTRACE_HOOKS @@ -202,17 +204,24 @@ trap(struct trapframe *frame) goto out; } -#ifdef HWPMC_HOOKS - /* - * CPU PMCs interrupt using an NMI. If the PMC module is - * active, pass the 'rip' value to the PMC module's interrupt - * handler. A return value of '1' from the handler means that - * the NMI was handled by it and we can return immediately. - */ - if (type == T_NMI && pmc_intr && - (*pmc_intr)(PCPU_GET(cpuid), frame)) - goto out; + if (type == T_NMI) { +#ifdef HWPMC_HOOKS + /* + * CPU PMCs interrupt using an NMI. If the PMC module is + * active, pass the 'rip' value to the PMC module's interrupt + * handler. A non-zero return value from the handler means that + * the NMI was consumed by it and we can return immediately. + */ + if (pmc_intr != NULL && + (*pmc_intr)(PCPU_GET(cpuid), frame) != 0) + goto out; +#endif + +#ifdef STACK + if (stack_nmi_handler(frame) != 0) + goto out; #endif + } if (type == T_MCHK) { mca_intr(); |