lkml.org 
[lkml]   [1999]   [Nov]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: Stack trace without forcing oops (was 2.2.14pre5: kmem_grow: Called nonatomically)
This can also be accomplished with the 'trace' command if you're
using 'lcrash' from the LKCD patch to 2.2.13, but from user land.
Of course, it's more than likely you're looking at a moving target
in the kernel (unless the task is waiting on a semaphore or some
other lock mechanism).

--Matt

On Sun, 21 Nov 1999, Keith Owens wrote:
|>On Sat, 20 Nov 1999 14:38:40 +0100 (CET),
|>Ingo Molnar <mingo@chiara.csoma.elte.hu> wrote:
|>>On Thu, 18 Nov 1999, Dominik Kubla wrote:
|>>> Hmm... nice! Is there a way to get a stacktrace without forcing an oops?
|>>nevertheless just changing show_task() or die_if_kernel() to not crash the
|>>the process if called in some special way could indeed be a welcome
|>>addition - but i believe only if it doesnt increase maintainance efforts.
|>
|>Easier than that. Break the stack dump code from show_registers() into
|>a separate routine, patch below. Any code that needs a back trace for
|>debugging can call show_stack(NULL). This also fixes a long standing
|>bug where the i386 stack was not completely printed if it went into the
|>second stack page.
|>
|>This patch is only for i386. It would be nice if all architectures had
|>a standard show_stack() routine. Against 2.3.28.
|>
|>Index: 28.1/arch/i386/kernel/i386_ksyms.c
|>--- 28.1/arch/i386/kernel/i386_ksyms.c Fri, 12 Nov 1999 18:53:00 +1100 keith (linux-2.3/w/37_i386_ksyms 1.9 644)
|>+++ 28.1(w)/arch/i386/kernel/i386_ksyms.c Sun, 21 Nov 1999 13:33:31 +1100 keith (linux-2.3/w/37_i386_ksyms 1.9 644)
|>@@ -130,3 +130,4 @@
|> #endif
|>
|> EXPORT_SYMBOL(get_wchan);
|>+EXPORT_SYMBOL(show_stack); /* For adhoc debugging in modules */
|>Index: 28.1/arch/i386/kernel/traps.c
|>--- 28.1/arch/i386/kernel/traps.c Sat, 23 Oct 1999 15:35:04 +1000 keith (linux-2.3/x/0_traps.c 1.7 644)
|>+++ 28.1(w)/arch/i386/kernel/traps.c Sun, 21 Nov 1999 19:58:17 +1100 keith (linux-2.3/x/0_traps.c 1.7 644)
|>@@ -129,13 +129,59 @@
|> #define VMALLOC_OFFSET (8*1024*1024)
|> #define MODULE_RANGE (8*1024*1024)
|>
|>+/* Separate show_stack() so adhoc debugging code can use it */
|>+void show_stack(const unsigned long *esp)
|>+{
|>+ int i;
|>+ unsigned long *stack, *save_stack, addr, module_start, module_end;
|>+ printk("Stack: ");
|>+ /* show_registers passes a real esp, adhoc debugging passes NULL */
|>+ if (esp)
|>+ stack = (unsigned long *) esp;
|>+ else
|>+ asm("movl %%esp,%0": "=m" (stack));
|>+ save_stack = stack;
|>+ for(i=0; i < kstack_depth_to_print; i++) {
|>+ if (((long) stack & ~PAGE_MASK) == 0)
|>+ break;
|>+ if (i && ((i % 8) == 0))
|>+ printk("\n ");
|>+ printk("%08lx ", *stack++);
|>+ }
|>+ printk("\nCall Trace: ");
|>+ stack = save_stack;
|>+ i = 1;
|>+ module_start = PAGE_OFFSET + (max_mapnr << PAGE_SHIFT);
|>+ module_start = ((module_start + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1));
|>+ module_end = module_start + MODULE_RANGE;
|>+ while (((long) stack & ~PAGE_MASK) != 0) {
|>+ addr = *stack++;
|>+ /*
|>+ * If the address is either in the text segment of the
|>+ * kernel, or in the region which contains vmalloc'ed
|>+ * memory, it *may* be the address of a calling
|>+ * routine; if so, print it so that someone tracing
|>+ * down the cause of the crash will be able to figure
|>+ * out the call path that was taken.
|>+ */
|>+ if (((addr >= (unsigned long) &_stext) &&
|>+ (addr <= (unsigned long) &_etext)) ||
|>+ ((addr >= module_start) && (addr <= module_end))) {
|>+ if (i && ((i % 8) == 0))
|>+ printk("\n ");
|>+ printk("[<%08lx>] ", addr);
|>+ i++;
|>+ }
|>+ }
|>+ printk("\n");
|>+}
|>+
|> static void show_registers(struct pt_regs *regs)
|> {
|> int i;
|> int in_kernel = 1;
|> unsigned long esp;
|> unsigned short ss;
|>- unsigned long *stack, addr, module_start, module_end;
|>
|> esp = (unsigned long) (1+regs);
|> ss = __KERNEL_DS;
|>@@ -152,52 +198,19 @@
|> regs->esi, regs->edi, regs->ebp, esp);
|> printk("ds: %04x es: %04x ss: %04x\n",
|> regs->xds & 0xffff, regs->xes & 0xffff, ss);
|>- printk("Process %s (pid: %d, stackpage=%08lx)",
|>+ printk("Process %s (pid: %d, stackpage=%08lx)\n",
|> current->comm, current->pid, 4096+(unsigned long)current);
|> /*
|> * When in-kernel, we also print out the stack and code at the
|> * time of the fault..
|> */
|> if (in_kernel) {
|>- printk("\nStack: ");
|>- stack = (unsigned long *) esp;
|>- for(i=0; i < kstack_depth_to_print; i++) {
|>- if (((long) stack & 4095) == 0)
|>- break;
|>- if (i && ((i % 8) == 0))
|>- printk("\n ");
|>- printk("%08lx ", *stack++);
|>- }
|>- printk("\nCall Trace: ");
|>- stack = (unsigned long *) esp;
|>- i = 1;
|>- module_start = PAGE_OFFSET + (max_mapnr << PAGE_SHIFT);
|>- module_start = ((module_start + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1));
|>- module_end = module_start + MODULE_RANGE;
|>- while (((long) stack & 4095) != 0) {
|>- addr = *stack++;
|>- /*
|>- * If the address is either in the text segment of the
|>- * kernel, or in the region which contains vmalloc'ed
|>- * memory, it *may* be the address of a calling
|>- * routine; if so, print it so that someone tracing
|>- * down the cause of the crash will be able to figure
|>- * out the call path that was taken.
|>- */
|>- if (((addr >= (unsigned long) &_stext) &&
|>- (addr <= (unsigned long) &_etext)) ||
|>- ((addr >= module_start) && (addr <= module_end))) {
|>- if (i && ((i % 8) == 0))
|>- printk("\n ");
|>- printk("[<%08lx>] ", addr);
|>- i++;
|>- }
|>- }
|>- printk("\nCode: ");
|>+ show_stack(&esp);
|>+ printk("Code: ");
|> for(i=0;i<20;i++)
|> printk("%02x ", ((unsigned char *)regs->eip)[i]);
|>+ printk("\n");
|> }
|>- printk("\n");
|> }
|>
|> spinlock_t die_lock;
|>Index: 28.1/include/linux/kernel.h
|>--- 28.1/include/linux/kernel.h Sat, 23 Oct 1999 15:35:04 +1000 keith (linux-2.3/F/b/4_kernel.h 1.7 644)
|>+++ 28.1(w)/include/linux/kernel.h Sun, 21 Nov 1999 14:08:36 +1100 keith (linux-2.3/F/b/4_kernel.h 1.7 644)
|>@@ -42,6 +42,7 @@
|> #define FASTCALL(x) x
|> #endif
|>
|>+extern void show_stack(const unsigned long *); /* For adhoc debugging */
|> extern void math_error(void);
|> extern struct notifier_block *panic_notifier_list;
|> NORET_TYPE void panic(const char * fmt, ...)
|>
|>
|>-
|>To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
|>the body of a message to majordomo@vger.rutgers.edu
|>Please read the FAQ at http://www.tux.org/lkml/
|>


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:55    [W:0.057 / U:0.196 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site