[PATCH] x86_64: (resend) x86_64 stack overflow debugging

Take two, now without spurious whitespace :(  Applies to git & 2.6.17-rc6

CONFIG_DEBUG_STACKOVERFLOW existed for x86_64 in 2.4, but seems to have gone AWOL in 2.6.

I've pretty much just copied this over from the 2.4 code, with
appropriate tweaks for the 2.6 kernel, plus a bugfix.  I'd personally
rather see it printed out the way other arches do it, i.e.
bytes-remaining-until-overflow, rather than having to do the subtraction
yourself.  Also, only 128 bytes remaining seems awfully late to issue a
warning.  But I'll start here :)

Signed-off-by: Eric Sandeen <sandeen@sgi.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Eric Sandeen 2006-06-26 14:00:05 +02:00 committed by Linus Torvalds
parent a4cffb6444
commit 4961f10e22
2 changed files with 34 additions and 1 deletions

View File

@ -35,6 +35,13 @@ config IOMMU_LEAK
Add a simple leak tracer to the IOMMU code. This is useful when you
are debugging a buggy device driver that leaks IOMMU mappings.
config DEBUG_STACKOVERFLOW
bool "Check for stack overflows"
depends on DEBUG_KERNEL
help
This option will cause messages to be printed if free stack space
drops below a certain limit.
#config X86_REMOTE_DEBUG
# bool "kgdb debugging stub"

View File

@ -26,6 +26,30 @@ atomic_t irq_mis_count;
#endif
#endif
#ifdef CONFIG_DEBUG_STACKOVERFLOW
/*
* Probabilistic stack overflow check:
*
* Only check the stack in process context, because everything else
* runs on the big interrupt stacks. Checking reliably is too expensive,
* so we just check from interrupts.
*/
static inline void stack_overflow_check(struct pt_regs *regs)
{
u64 curbase = (u64) current->thread_info;
static unsigned long warned = -60*HZ;
if (regs->rsp >= curbase && regs->rsp <= curbase + THREAD_SIZE &&
regs->rsp < curbase + sizeof(struct thread_info) + 128 &&
time_after(jiffies, warned + 60*HZ)) {
printk("do_IRQ: %s near stack overflow (cur:%Lx,rsp:%lx)\n",
current->comm, curbase, regs->rsp);
show_stack(NULL,NULL);
warned = jiffies;
}
}
#endif
/*
* Generic, controller-independent functions:
*/
@ -96,7 +120,9 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
exit_idle();
irq_enter();
#ifdef CONFIG_DEBUG_STACKOVERFLOW
stack_overflow_check(regs);
#endif
__do_IRQ(irq, regs);
irq_exit();