public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Adam Litke <agl@us.ibm.com>
To: Andrew Morton <akpm@osdl.org>
Cc: roland@topspin.com, mlxk@mellanox.co.il, linux-kernel@vger.kernel.org
Subject: Re: stack dumps, CONFIG_FRAME_POINTER and i386 (was Re: sysrq shows impossible call stack)
Date: Thu, 22 Apr 2004 11:25:10 -0700	[thread overview]
Message-ID: <1082658310.715.224.camel@agtpad> (raw)
In-Reply-To: <20040421165059.4579e64d.akpm@osdl.org>

On Wed, 2004-04-21 at 16:50, Andrew Morton wrote:
> Adam Litke <agl@us.ibm.com> wrote:
> >
> > On Tue, 2004-04-20 at 18:41, Andrew Morton wrote:
> > > Andrew Morton <akpm@osdl.org> wrote:
> > > >
> > > > Roland Dreier <roland@topspin.com> wrote:
> > > >  >
> > > >  >     Adam> This problem was annoying me a few months ago so I coded up
> > > >  >     Adam> a stack trace patch that actually uses the frame pointer.
> > > >  >     Adam> It is currently maintained in -mjb but I have pasted below.
> > > >  >     Adam> Hope this helps.
> > > >  > 
> > > >  > Thanks, that looks really useful.  What is the chance of this moving
> > > >  > from -mjb to mainline?
> > > > 
> > > >  Good, but it needs to be updated to do the right thing with 4k stacks when
> > > >  called from interrupt context.
> > 
> > The show_trace() for the CONFIG_FRAME_POINTER case will now be called
> > the same way as the existing code.
> 
> I still don't see any code in there to handle the transition from the
> interrupt stack page to the non-interrupt stack page in the 4k-stacks case?

Ok here is the latest version of the patch.  I added support for the
4k-stacks interrupt stack case.  I also moved some things around to
minimize code duplication.  Andrew, how does this look?

diff -purN linux-2.6.5-bk/arch/i386/kernel/traps.c linux-2.6.5-bk-stack/arch/i386/kernel/traps.c
--- linux-2.6.5-bk/arch/i386/kernel/traps.c	Thu Apr 22 09:10:57 2004
+++ linux-2.6.5-bk-stack/arch/i386/kernel/traps.c	Thu Apr 22 10:57:39 2004
@@ -92,29 +92,84 @@ asmlinkage void alignment_check(void);
 asmlinkage void spurious_interrupt_bug(void);
 asmlinkage void machine_check(void);
 
-static int kstack_depth_to_print = 24;
+#define valid_stack_ptr(task, p) \
+	((struct thread_info*)p > task->thread_info) && \
+	 !kstack_end((unsigned long*)p)
 
-void show_trace(struct task_struct *task, unsigned long * stack)
+#ifdef CONFIG_FRAME_POINTER
+void show_stack_frame(unsigned long start, unsigned long end)
+{
+	unsigned long i;
+
+	printk("              ");
+	for (i = start; i < end; i += 4) {
+		if ((i - start) && ((i - start)%24 == 0))
+			printk("\n              ");
+		printk("%08lx ", *(unsigned long *) i);
+	}
+	printk("\n");
+}
+
+void print_context_stack(struct task_struct *task, unsigned long * stack, 
+			 unsigned long ebp)
 {
 	unsigned long addr;
 
-	if (!stack)
-		stack = (unsigned long*)&stack;
+	show_stack_frame((unsigned long) stack, ebp + 4);
+	while (valid_stack_ptr(task, ebp)) {
+		addr = *(unsigned long *) (ebp + 4);
+		printk(" [<%08lx>] ", addr);
+		print_symbol("%s", addr);
+		printk("\n");
+
+		/* Show the stack frame (excluding the frame pointer) */
+		show_stack_frame(ebp + 8, (*(unsigned long *) ebp) + 4);
+		ebp = *(unsigned long *) ebp;
+	}
+}
+#else
+int kstack_depth_to_print = 24;
+
+void print_context_stack(struct task_struct *task, unsigned long * stack,
+			 unsigned long ebp)
+{
+	unsigned long addr;
 
-	printk("Call Trace:");
-#ifdef CONFIG_KALLSYMS
-	printk("\n");
+	while (!kstack_end(stack)) {
+		addr = *stack++;
+		if (kernel_text_address(addr)) {
+			printk(" [<%08lx>] ", addr);
+			print_symbol("%s\n", addr);
+		}
+	}
+}
 #endif
+
+void show_trace(struct task_struct *task, unsigned long * stack)
+{
+	unsigned long ebp;
+
+	if (!task)
+		task = current;
+	
+	if (!valid_stack_ptr(task, stack)) {
+		printk("Stack pointer is garbage, not printing trace\n");
+		return;
+	}
+	
+	if (task == current) {
+		/* Grab ebp right from our regs */
+		asm ("movl %%ebp, %0" : "=r" (ebp) : );
+	} else {
+		/* ebp is the last reg pushed by switch_to */
+		ebp = *(unsigned long *) task->thread.esp;
+	}
+	
 	while (1) {
 		struct thread_info *context;
-		context = (struct thread_info*) ((unsigned long)stack & (~(THREAD_SIZE - 1)));
-		while (!kstack_end(stack)) {
-			addr = *stack++;
-			if (kernel_text_address(addr)) {
-				printk(" [<%08lx>] ", addr);
-				print_symbol("%s\n", addr);
-			}
-		}
+		context = (struct thread_info*) 
+			((unsigned long)stack & (~(THREAD_SIZE - 1)));
+		print_context_stack(task, stack, ebp);
 		stack = (unsigned long*)context->previous_esp;
 		if (!stack)
 			break;
@@ -135,9 +190,6 @@ void show_trace_task(struct task_struct 
 
 void show_stack(struct task_struct *task, unsigned long *esp)
 {
-	unsigned long *stack;
-	int i;
-
 	if (esp == NULL) {
 		if (task)
 			esp = (unsigned long*)task->thread.esp;
@@ -145,6 +197,10 @@ void show_stack(struct task_struct *task
 			esp = (unsigned long *)&esp;
 	}
 
+#ifndef CONFIG_FRAME_POINTER
+	{
+	unsigned long *stack;
+	int i;
 	stack = esp;
 	for(i = 0; i < kstack_depth_to_print; i++) {
 		if (kstack_end(stack))
@@ -154,6 +210,8 @@ void show_stack(struct task_struct *task
 		printk("%08lx ", *stack++);
 	}
 	printk("\n");
+	}
+#endif
 	show_trace(task, esp);
 }
 

-- 
Adam Litke - (agl at us.ibm.com)
IBM Linux Technology Center


      reply	other threads:[~2004-04-22 18:27 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-04-20 15:45 sysrq shows impossible call stack Eli Cohen
2004-04-20 16:26 ` Roland Dreier
2004-04-20 17:36   ` Eli Cohen
2004-04-20 17:51     ` stack dumps, CONFIG_FRAME_POINTER and i386 (was Re: sysrq shows impossible call stack) Roland Dreier
2004-04-20 20:26       ` Adam Litke
2004-04-21  0:12         ` Roland Dreier
2004-04-21  1:39           ` Andrew Morton
2004-04-21  1:41             ` Andrew Morton
2004-04-21 23:28               ` Adam Litke
2004-04-21 23:50                 ` Andrew Morton
2004-04-22 18:25                   ` Adam Litke [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1082658310.715.224.camel@agtpad \
    --to=agl@us.ibm.com \
    --cc=akpm@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mlxk@mellanox.co.il \
    --cc=roland@topspin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox