mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Jan Beulich" <jbeulich@novell.com>
To: "Andi Kleen" <ak@suse.de>
Cc: <linux-kernel@vger.kernel.org>, <patches@x86-64.org>
Subject: Re: backtracer stuck in apic_timer_interrupt
Date: Tue, 15 Aug 2006 12:53:22 +0200	[thread overview]
Message-ID: <44E1C3C2.76E4.0078.0@novell.com> (raw)
In-Reply-To: <200608040920.42076.ak@suse.de>

>Do you know why the backtracer gets stuck in apic_timer_interrupt?
>Somehow it didn't manage to go over to the process stack, but it
should
>have.

No, I don't, I just verified that the annotations are correct (in that
unwinds can pass this function). If you see this again, I'd need the
raw
stack dump to compare. However, while doing this I also saw a case
where it wouldn't properly unwind (but one level up from
apic_timer_interrupt), however in this case it was expectedly getting
stuck because the interrupt had hit a procedure that already entered
it
epilogue, which gcc fails to annotate.

Further, while doing this, I found myself ending up with an unwound
stack trace followed by a legacy one, but without any separator
indicating so. Therefore I looked at the fallback logic you recently
changed and found that it was still not quite right. Hence I created
below patch (for both i386 and x86-64).

Jan

The unwinder fallback logic still had potential for falling through to
the legacy stack trace code without printing an indication (at once
serving as a separator) of this.

Further, the stack pointer retrieval for the fallback should be as
restrictive as possible (in order to avoid having the legacy stack
tracer try to access invalid memory). The patch tightens that, but
this could certainly be further improved.

Also making the call_trace command line option now conditional upon
CONFIG_STACK_UNWIND (as it's meaningless otherwise).

Signed-off-by: Jan Beulich <jbeulich@novell.com>

--- linux-2.6.18-rc4/arch/i386/kernel/traps.c	2006-08-15
11:29:35.000000000 +0200
+++
2.6.18-rc4-unwind-x86-fallback/arch/i386/kernel/traps.c	2006-08-15
10:52:43.000000000 +0200
@@ -92,7 +92,11 @@ asmlinkage void spurious_interrupt_bug(v
 asmlinkage void machine_check(void);
 
 static int kstack_depth_to_print = 24;
+#ifdef CONFIG_STACK_UNWIND
 static int call_trace = 1;
+#else
+#define call_trace (-1)
+#endif
 ATOMIC_NOTIFIER_HEAD(i386die_chain);
 
 int register_die_notifier(struct notifier_block *nb)
@@ -187,22 +191,21 @@ static void show_trace_log_lvl(struct ta
 			if (unwind_init_blocked(&info, task) == 0)
 				unw_ret = show_trace_unwind(&info,
log_lvl);
 		}
-		if (unw_ret > 0 && !arch_unw_user_mode(&info)) {
-#ifdef CONFIG_STACK_UNWIND
-			print_symbol("DWARF2 unwinder stuck at %s\n",
-				     UNW_PC(&info));
-			if (call_trace == 1) {
-				printk("Leftover inexact
backtrace:\n");
-				if (UNW_SP(&info))
+		if (unw_ret > 0) {
+			if (call_trace == 1 &&
!arch_unw_user_mode(&info)) {
+				print_symbol("DWARF2 unwinder stuck at
%s\n",
+					     UNW_PC(&info));
+				if (UNW_SP(&info) >= PAGE_OFFSET) {
+					printk("Leftover inexact
backtrace:\n");
 					stack = (void *)UNW_SP(&info);
-			} else if (call_trace > 1)
+				} else
+					printk("Full inexact backtrace
again:\n");
+			} else if (call_trace >= 1)
 				return;
 			else
 				printk("Full inexact backtrace
again:\n");
-#else
+		} else
 			printk("Inexact backtrace:\n");
-#endif
-		}
 	}
 
 	if (task == current) {
@@ -1241,6 +1244,7 @@ static int __init kstack_setup(char *s)
 }
 __setup("kstack=", kstack_setup);
 
+#ifdef CONFIG_STACK_UNWIND
 static int __init call_trace_setup(char *s)
 {
 	if (strcmp(s, "old") == 0)
@@ -1254,3 +1258,4 @@ static int __init call_trace_setup(char 
 	return 1;
 }
 __setup("call_trace=", call_trace_setup);
+#endif
--- linux-2.6.18-rc4/arch/x86_64/kernel/traps.c	2006-08-15
11:29:41.000000000 +0200
+++
2.6.18-rc4-unwind-x86-fallback/arch/x86_64/kernel/traps.c	2006-08-15
10:49:34.000000000 +0200
@@ -107,7 +107,11 @@ static inline void preempt_conditional_c
 }
 
 static int kstack_depth_to_print = 12;
+#ifdef CONFIG_STACK_UNWIND
 static int call_trace = 1;
+#else
+#define call_trace (-1)
+#endif
 
 #ifdef CONFIG_KALLSYMS
 # include <linux/kallsyms.h>
@@ -274,21 +278,21 @@ void show_trace(struct task_struct *tsk,
 			if (unwind_init_blocked(&info, tsk) == 0)
 				unw_ret = show_trace_unwind(&info,
NULL);
 		}
-		if (unw_ret > 0 && !arch_unw_user_mode(&info)) {
-#ifdef CONFIG_STACK_UNWIND
-			unsigned long rip = info.regs.rip;
-			print_symbol("DWARF2 unwinder stuck at %s\n",
rip);
-			if (call_trace == 1) {
-				printk("Leftover inexact
backtrace:\n");
-				stack = (unsigned long *)info.regs.rsp;
-			} else if (call_trace > 1)
+		if (unw_ret > 0) {
+			if (call_trace == 1 &&
!arch_unw_user_mode(&info)) {
+				print_symbol("DWARF2 unwinder stuck at
%s\n",
+					     UNW_PC(&info));
+				if ((long)UNW_SP(&info) < 0) {
+					printk("Leftover inexact
backtrace:\n");
+					stack = (unsigned long
*)UNW_SP(&info);
+				} else
+					printk("Full inexact backtrace
again:\n");
+			} else if (call_trace >= 1)
 				return;
 			else
 				printk("Full inexact backtrace
again:\n");
-#else
+		} else
 			printk("Inexact backtrace:\n");
-#endif
-		}
 	}
 
 	/*
@@ -1120,6 +1124,7 @@ static int __init kstack_setup(char *s)
 }
 __setup("kstack=", kstack_setup);
 
+#ifdef CONFIG_STACK_UNWIND
 static int __init call_trace_setup(char *s)
 {
 	if (strcmp(s, "old") == 0)
@@ -1133,3 +1138,4 @@ static int __init call_trace_setup(char 
 	return 1;
 }
 __setup("call_trace=", call_trace_setup);
+#endif
--- linux-2.6.18-rc4/include/asm-i386/unwind.h	2006-08-15
11:30:00.000000000 +0200
+++
2.6.18-rc4-unwind-x86-fallback/include/asm-i386/unwind.h	2006-08-15
09:36:19.000000000 +0200
@@ -87,6 +87,7 @@ static inline int arch_unw_user_mode(con
 #else
 
 #define UNW_PC(frame) ((void)(frame), 0)
+#define UNW_SP(frame) ((void)(frame), 0)
 
 static inline int arch_unw_user_mode(const void *info)
 {
--- linux-2.6.18-rc4/include/asm-x86_64/unwind.h	2006-08-15
11:30:02.000000000 +0200
+++
2.6.18-rc4-unwind-x86-fallback/include/asm-x86_64/unwind.h	2006-08-15
09:36:19.000000000 +0200
@@ -95,6 +95,7 @@ static inline int arch_unw_user_mode(con
 #else
 
 #define UNW_PC(frame) ((void)(frame), 0)
+#define UNW_SP(frame) ((void)(frame), 0)
 
 static inline int arch_unw_user_mode(const void *info)
 {


       reply	other threads:[~2006-08-15 10:53 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <200608040920.42076.ak@suse.de>
2006-08-15 10:53 ` Jan Beulich [this message]
2006-08-15 11:18   ` [patches] " Andi Kleen

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=44E1C3C2.76E4.0078.0@novell.com \
    --to=jbeulich@novell.com \
    --cc=ak@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=patches@x86-64.org \
    /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

Powered by JetHome