* Re: _stext is ill-defined / SysRq-T broken
2002-07-25 10:08 ` Maciej W. Rozycki
@ 2002-07-25 11:05 ` Johannes Stezenbach
2002-07-25 11:20 ` Maciej W. Rozycki
2002-07-25 11:47 ` Johannes Stezenbach
2002-07-29 13:25 ` [patch] Oops and magic SysRq stack dump clean-ups Maciej W. Rozycki
2 siblings, 1 reply; 7+ messages in thread
From: Johannes Stezenbach @ 2002-07-25 11:05 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: linux-mips
On Thu, Jul 25, 2002 at 12:08:15PM +0200, Maciej W. Rozycki wrote:
>
> I think the intent is to skip initial parts of .text, specifically the
> exception handlers (if linked at KSEG0). kernel_entry is in .text.init
> deliberately, as it's not needed except early in the boot process. I
> propose the following change. Does it work for you?
>
> diff -up --recursive --new-file linux-mips-2.4.19-rc1-20020719.macro/arch/mips/kernel/head.S linux-mips-2.4.19-rc1-20020719/arch/mips/kernel/head.S
> --- linux-mips-2.4.19-rc1-20020719.macro/arch/mips/kernel/head.S 2002-06-04 03:04:12.000000000 +0000
> +++ linux-mips-2.4.19-rc1-20020719/arch/mips/kernel/head.S 2002-07-25 10:03:16.000000000 +0000
> @@ -35,6 +35,10 @@
> */
> .fill 0x400
>
> + /* The following two symbols are used for kernel profiling. */
> + EXPORT(stext)
> + EXPORT(_stext)
> +
> __INIT
>
> /* Cache Error */
> @@ -144,9 +148,6 @@ ejtag_return:
> */
> NESTED(kernel_entry, 16, sp)
> .set noreorder
> - /* The following two symbols are used for kernel profiling. */
> - EXPORT(stext)
> - EXPORT(_stext)
>
> /*
> * Stack for kernel and init, current variable
>
Yes, works.
Just one nit while we're at it:
On most systems the .fill 0x400 is unnecessary and wastes 1KB (more
than the .text.init size of head.o). Wouldn't it be better to remove the
.fill and require the LOADADDR in arch/mips/Makefile to be >= 0x80000400?
Johannes
^ permalink raw reply [flat|nested] 7+ messages in thread
* [patch] Oops and magic SysRq stack dump clean-ups
2002-07-25 10:08 ` Maciej W. Rozycki
2002-07-25 11:05 ` Johannes Stezenbach
2002-07-25 11:47 ` Johannes Stezenbach
@ 2002-07-29 13:25 ` Maciej W. Rozycki
2002-07-29 16:02 ` Johannes Stezenbach
2 siblings, 1 reply; 7+ messages in thread
From: Maciej W. Rozycki @ 2002-07-29 13:25 UTC (permalink / raw)
To: Johannes Stezenbach, Ralf Baechle, linux-mips, linux-mips
Hello,
I've reviewed the stack dumping code more thoroughly and here is the
result. Please check if it's OK for you. Tested visually with oopses and
<SysRq>+<t> on MIPS/Linux and MIPS64/Linux. The idea is to fit as much
data as possible in as little space as possible and at the same time lay
the numbers out visually nicely so that manual copying of output from a
terminal for ksymoops analysis is easier for a reader. Tools ignore
spacing when processing such output anyway.
Based somewhat on the i386 port. Addresses cast to signed longs, since
they are such on MIPS (additionally, the code doesn't care anyway but the
resulting source is smaller). Any objections?
Maciej
--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: macro@ds2.pg.gda.pl, PGP key available +
patch-mips-2.4.19-rc1-20020719-mips-show_trace-8
diff -up --recursive --new-file linux-mips-2.4.19-rc1-20020719.macro/arch/mips/kernel/traps.c linux-mips-2.4.19-rc1-20020719/arch/mips/kernel/traps.c
--- linux-mips-2.4.19-rc1-20020719.macro/arch/mips/kernel/traps.c 2002-07-08 16:46:04.000000000 +0000
+++ linux-mips-2.4.19-rc1-20020719/arch/mips/kernel/traps.c 2002-07-27 11:48:19.000000000 +0000
@@ -181,61 +181,95 @@ static inline void simulate_sc(struct pt
}
/*
+ * If the address is either in the .text section of the
+ * kernel, or in the vmalloc'ed module regions, it *may*
+ * be the address of a calling routine
+ */
+
+#ifdef CONFIG_MODULES
+
+extern struct module *module_list;
+extern struct module kernel_module;
+
+static inline int kernel_text_address(long addr)
+{
+ extern char _stext, _etext;
+ int retval = 0;
+ struct module *mod;
+
+ if (addr >= (long) &_stext && addr <= (long) &_etext)
+ return 1;
+
+ for (mod = module_list; mod != &kernel_module; mod = mod->next) {
+ /* mod_bound tests for addr being inside the vmalloc'ed
+ * module area. Of course it'd be better to test only
+ * for the .text subset... */
+ if (mod_bound(addr, 0, mod)) {
+ retval = 1;
+ break;
+ }
+ }
+
+ return retval;
+}
+
+#else
+
+static inline int kernel_text_address(long addr)
+{
+ extern char _stext, _etext;
+
+ return (addr >= (long) &_stext && addr <= (long) &_etext);
+}
+
+#endif
+
+/*
* This routine abuses get_user()/put_user() to reference pointers
* with at least a bit of error checking ...
*/
-void show_stack(unsigned int *sp)
+void show_stack(long *sp)
{
int i;
- unsigned int *stack;
-
- stack = sp ? sp : (unsigned int *)&sp;
- i = 0;
+ long stackdata;
- printk("Stack:");
- while ((unsigned long) stack & (PAGE_SIZE - 1)) {
- unsigned long stackdata;
+ sp = sp ? sp : (long *)&sp;
- if (__get_user(stackdata, stack++)) {
- printk(" (Bad stack address)");
+ printk("Stack: ");
+ i = 1;
+ while ((long) sp & (PAGE_SIZE - 1)) {
+ if (i && ((i % 8) == 0))
+ printk("\n");
+ if (i > 40) {
+ printk(" ...");
break;
}
- printk(" %08lx", stackdata);
-
- if (++i > 40) {
- printk(" ...");
+ if (__get_user(stackdata, sp++)) {
+ printk(" (Bad stack address)");
break;
}
- if (i % 8 == 0)
- printk("\n ");
+ printk(" %08lx", stackdata);
+ i++;
}
+ printk("\n");
}
-void show_trace(unsigned int *sp)
+void show_trace(long *sp)
{
int i;
- int column = 0;
- unsigned int *stack;
- unsigned long kernel_start, kernel_end;
- unsigned long module_start, module_end;
- extern char _stext, _etext;
-
- stack = sp ? sp : (unsigned int *) &sp;
- i = 0;
-
- kernel_start = (unsigned long) &_stext;
- kernel_end = (unsigned long) &_etext;
- module_start = VMALLOC_START;
- module_end = module_start + MODULE_RANGE;
+ long addr;
- printk("\nCall Trace:");
+ sp = sp ? sp : (long *) &sp;
- while ((unsigned long) stack & (PAGE_SIZE -1)) {
- unsigned long addr;
+ printk("Call Trace: ");
+ i = 1;
+ while ((long) sp & (PAGE_SIZE - 1)) {
- if (__get_user(addr, stack++)) {
+ if (__get_user(addr, sp++)) {
+ if (i && ((i % 6) == 0))
+ printk("\n");
printk(" (Bad stack address)\n");
break;
}
@@ -249,27 +283,24 @@ void show_trace(unsigned int *sp)
* out the call path that was taken.
*/
- if ((addr >= kernel_start && addr < kernel_end) ||
- (addr >= module_start && addr < module_end)) {
-
- printk(" [<%08lx>]", addr);
- if (column++ == 5) {
+ if (kernel_text_address(addr)) {
+ if (i && ((i % 6) == 0))
printk("\n");
- column = 0;
- }
- if (++i > 40) {
+ if (i > 40) {
printk(" ...");
break;
}
+
+ printk(" [<%08lx>]", addr);
+ i++;
}
}
- if (column != 0)
- printk("\n");
+ printk("\n");
}
void show_trace_task(struct task_struct *tsk)
{
- show_trace((unsigned int *)tsk->thread.reg29);
+ show_trace((long *)tsk->thread.reg29);
}
void show_code(unsigned int *pc)
@@ -321,8 +352,8 @@ void show_registers(struct pt_regs *regs
show_regs(regs);
printk("Process %s (pid: %d, stackpage=%08lx)\n",
current->comm, current->pid, (unsigned long) current);
- show_stack((unsigned int *) regs->regs[29]);
- show_trace((unsigned int *) regs->regs[29]);
+ show_stack((long *) regs->regs[29]);
+ show_trace((long *) regs->regs[29]);
show_code((unsigned int *) regs->cp0_epc);
printk("\n");
}
diff -up --recursive --new-file linux-mips-2.4.19-rc1-20020719.macro/arch/mips64/kernel/traps.c linux-mips-2.4.19-rc1-20020719/arch/mips64/kernel/traps.c
--- linux-mips-2.4.19-rc1-20020719.macro/arch/mips64/kernel/traps.c 2002-07-08 16:46:08.000000000 +0000
+++ linux-mips-2.4.19-rc1-20020719/arch/mips64/kernel/traps.c 2002-07-27 11:43:15.000000000 +0000
@@ -70,60 +70,91 @@ int kstack_depth_to_print = 24;
#define OPCODE 0xfc000000
/*
+ * If the address is either in the .text section of the
+ * kernel, or in the vmalloc'ed module regions, it *may*
+ * be the address of a calling routine
+ */
+
+#ifdef CONFIG_MODULES
+
+extern struct module *module_list;
+extern struct module kernel_module;
+
+static inline int kernel_text_address(long addr)
+{
+ extern char _stext, _etext;
+ int retval = 0;
+ struct module *mod;
+
+ if (addr >= (long) &_stext && addr <= (long) &_etext)
+ return 1;
+
+ for (mod = module_list; mod != &kernel_module; mod = mod->next) {
+ /* mod_bound tests for addr being inside the vmalloc'ed
+ * module area. Of course it'd be better to test only
+ * for the .text subset... */
+ if (mod_bound(addr, 0, mod)) {
+ retval = 1;
+ break;
+ }
+ }
+
+ return retval;
+}
+
+#else
+
+static inline int kernel_text_address(long addr)
+{
+ extern char _stext, _etext;
+
+ return (addr >= (long) &_stext && addr <= (long) &_etext);
+}
+
+#endif
+
+/*
* This routine abuses get_user()/put_user() to reference pointers
* with at least a bit of error checking ...
*/
-void show_stack(unsigned long *sp)
+void show_stack(long *sp)
{
int i;
- unsigned long *stack;
-
- stack = sp;
- i = 0;
+ long stackdata;
printk("Stack:");
- while ((unsigned long) stack & (PAGE_SIZE - 1)) {
- unsigned long stackdata;
-
- if (__get_user(stackdata, stack++)) {
- printk(" (Bad stack address)");
+ i = 0;
+ while ((long) sp & (PAGE_SIZE - 1)) {
+ if (i && ((i % 4) == 0))
+ printk("\n ");
+ if (i > 40) {
+ printk(" ...");
break;
}
- printk(" %016lx", stackdata);
-
- if (++i > 40) {
- printk(" ...");
+ if (__get_user(stackdata, sp++)) {
+ printk(" (Bad stack address)");
break;
}
- if (i % 4 == 0)
- printk("\n ");
+ printk(" %016lx", stackdata);
+ i++;
}
+ printk("\n");
}
-void show_trace(unsigned long *sp)
+void show_trace(long *sp)
{
int i;
- unsigned long *stack;
- unsigned long kernel_start, kernel_end;
- unsigned long module_start, module_end;
- extern char _stext, _etext;
+ long addr;
- stack = sp;
+ printk("Call Trace:");
i = 0;
+ while ((long) sp & (PAGE_SIZE - 1)) {
- kernel_start = (unsigned long) &_stext;
- kernel_end = (unsigned long) &_etext;
- module_start = VMALLOC_START;
- module_end = module_start + MODULE_RANGE;
-
- printk("\nCall Trace:");
-
- while ((unsigned long) stack & (PAGE_SIZE - 1)) {
- unsigned long addr;
-
- if (__get_user(addr, stack++)) {
+ if (__get_user(addr, sp++)) {
+ if (i && ((i % 3) == 0))
+ printk("\n ");
printk(" (Bad stack address)\n");
break;
}
@@ -137,25 +168,24 @@ void show_trace(unsigned long *sp)
* out the call path that was taken.
*/
- if ((addr >= kernel_start && addr < kernel_end) ||
- (addr >= module_start && addr < module_end)) {
-
- /* Since our kernel is still at KSEG0,
- * truncate the address so that ksymoops
- * understands it.
- */
- printk(" [<%08x>]", (unsigned int) addr);
- if (++i > 40) {
+ if (kernel_text_address(addr)) {
+ if (i && ((i % 3) == 0))
+ printk("\n ");
+ if (i > 40) {
printk(" ...");
break;
}
+
+ printk(" [<%016lx>]", addr);
+ i++;
}
}
+ printk("\n");
}
void show_trace_task(struct task_struct *tsk)
{
- show_trace((unsigned long *)tsk->thread.reg29);
+ show_trace((long *)tsk->thread.reg29);
}
@@ -224,8 +254,8 @@ void show_registers(struct pt_regs *regs
show_regs(regs);
printk("Process %s (pid: %d, stackpage=%016lx)\n",
current->comm, current->pid, (unsigned long) current);
- show_stack((unsigned long *) regs->regs[29]);
- show_trace((unsigned long *) regs->regs[29]);
+ show_stack((long *) regs->regs[29]);
+ show_trace((long *) regs->regs[29]);
show_code((unsigned int *) regs->cp0_epc);
printk("\n");
}
^ permalink raw reply [flat|nested] 7+ messages in thread