[PATCH] Making show_registers() let you see the forest

Inaky Perez Gonzalez (inaky@peloncho.fis.ucm.es)
Sat, 22 Aug 1998 00:43:32 +0200


Hi

As a consequence of the piles of panics I often get when
poking the USB code, I cannot see what actually happened, lost in the
sea of kernel dumps. I've made a little patch, which is _VERY_ raw
quite now, but works.

It allows you to specify if you want, and how many, output on
kernel dumps, so you can reduce or eliminate the stack, call or code
traces at will, via /proc/sys/kernel/. This way, the output is cleaner
and you can see how it happens, regards the fifteen sequential dumps
for page fault on irq handler :)

Sugerences welcome ... [done on 2.1.116, others untested, but
hey, it's too simple to fail, I think :)]

--- linux/kernel/sysctl.c.original Fri Aug 21 01:07:06 1998
+++ linux/kernel/sysctl.c Fri Aug 21 20:21:59 1998
@@ -55,6 +55,19 @@
extern unsigned long htab_reclaim_on, zero_paged_on, powersave_nap;
#endif

+ /*
+ * Control kind of dump on show_registers() call. See
+ * arch/i386/traps.c. This is useful when too many sequential
+ * dumps don't allow you seeing what's actually happening [aka:
+ * the trees won't let you contemplate the forest].
+ */
+
+#ifdef __i386__
+extern int kstack_depth_to_print;
+extern int ktrace_depth_to_print;
+extern int code_print;
+#endif
+
extern int pgt_cache_water[];

static int parse_table(int *, int, void *, size_t *, void *, size_t,
@@ -153,6 +166,14 @@
0644, NULL, &proc_doutsstring, &sysctl_string},
{KERN_PANIC, "panic", &panic_timeout, sizeof(int),
0644, NULL, &proc_dointvec},
+#ifdef __i386__
+ {KERN_KSTK_DTP, "stack-dump-depth", &kstack_depth_to_print, sizeof(int),
+ 0644, NULL, &proc_dointvec},
+ {KERN_KTRC_DTP, "trace-dump-depth", &ktrace_depth_to_print, sizeof(int),
+ 0644, NULL, &proc_dointvec},
+ {KERN_DUMP_CODE, "dump-code", &code_print, sizeof(int),
+ 0644, NULL, &proc_dointvec},
+#endif
#ifdef CONFIG_BLK_DEV_INITRD
{KERN_REALROOTDEV, "real-root-dev", &real_root_dev, sizeof(int),
0644, NULL, &proc_dointvec},
--- linux/include/linux/sysctl.h.original Fri Aug 21 01:07:06 1998
+++ linux/include/linux/sysctl.h Fri Aug 21 20:26:58 1998
@@ -56,6 +56,11 @@
KERN_DOMAINNAME,
KERN_SECURELVL, /* int: system security level */
KERN_PANIC, /* int: panic timeout */
+#ifdef __i386__
+ KERN_KSTK_DTP, /* int: depth of stack dump */
+ KERN_KTRC_DTP, /* int: depth of trace dump */
+ KERN_DUMP_CODE, /* int: dump code or not */
+#endif
KERN_REALROOTDEV, /* real root device to mount after initrd */
KERN_JAVA_INTERPRETER, /* path to Java(tm) interpreter */
KERN_JAVA_APPLETVIEWER, /* path to Java(tm) appletviewer */
--- linux/arch/i386/kernel/traps.c.original Fri Aug 21 01:07:09 1998
+++ linux/arch/i386/kernel/traps.c Fri Aug 21 20:25:02 1998
@@ -87,7 +87,18 @@
asmlinkage void alignment_check(void);
asmlinkage void spurious_interrupt_bug(void);

+ /*
+ * Control how much of dumps is printed on show_registers(). On
+ * all of them, 0 means print nothing; on ktrace, < 0 means print
+ * until over.
+ *
+ * Settable via /proc/sys/kernel. Please, update kernel/sysctl.c
+ * if you change this.
+ */
+
int kstack_depth_to_print = 24;
+int ktrace_depth_to_print = -1;
+int code_print = 1;

/*
* These constants are for searching for possible module text
@@ -114,59 +125,71 @@
ss = regs->xss & 0xffff;
}
printk("CPU: %d\nEIP: %04x:[<%08lx>]\nEFLAGS: %08lx\n",
- smp_processor_id(), 0xffff & regs->xcs, regs->eip, regs->eflags);
+ smp_processor_id(), 0xffff & regs->xcs, regs->eip, regs->eflags);
printk("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
- regs->eax, regs->ebx, regs->ecx, regs->edx);
+ regs->eax, regs->ebx, regs->ecx, regs->edx);
printk("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
- regs->esi, regs->edi, regs->ebp, esp);
+ regs->esi, regs->edi, regs->ebp, esp);
printk("ds: %04x es: %04x ss: %04x\n",
- regs->xds & 0xffff, regs->xes & 0xffff, ss);
+ regs->xds & 0xffff, regs->xes & 0xffff, ss);
store_TR(i);
printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
- current->comm, current->pid, 0xffff & i, 4096+(unsigned long)current);
+ current->comm, current->pid, 0xffff & i, 4096+(unsigned long)current);

- /*
- * When in-kernel, we also print out the stack and code at the
- * time of the fault..
- */
+ /*
+ * 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: ");
- for(i=0;i<20;i++)
- printk("%02x ", ((unsigned char *)regs->eip)[i]);
+ if (kstack_depth_to_print)
+ {
+ 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++);
+ }
+ }
+ if (ktrace_depth_to_print)
+ {
+ int depth = ktrace_depth_to_print;
+
+ 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 && depth) {
+ 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++;
+ }
+ depth--;
+ }
+ }
+ if (code_print)
+ {
+ printk("\nCode: ");
+ for(i=0;i<20;i++)
+ printk("%02x ", ((unsigned char *)regs->eip)[i]);
+ }
}
printk("\n");
}


-- 

Linux-USB! http://peloncho.fis.ucm.es/~inaky/USB.html - - Inaky Perez Gonzalez -- PGP pubkey fingerprint - inaky@peloncho.fis.ucm.es -- 8E 34 3A 62 64 99 E2 44 - http://peloncho.fis.ucm.es/~inaky -- AD 7B 30 D9 DD FF 3E 4C - --------------------------------- -- ----------------------- - The loneliness of the long distance runner .....

- 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.altern.org/andrebalsa/doc/lkml-faq.html