Skip to content

Commit

Permalink
[PATCH] x86_64: (resend) x86_64 stack overflow debugging
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Eric Sandeen authored and Linus Torvalds committed Jun 26, 2006
1 parent a4cffb6 commit 4961f10
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
7 changes: 7 additions & 0 deletions arch/x86_64/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
28 changes: 27 additions & 1 deletion arch/x86_64/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
*/
Expand Down Expand Up @@ -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();

Expand Down

0 comments on commit 4961f10

Please sign in to comment.