2.4.21-pre5 kksymoops for i386/ia64
PATCH 1/1 2.4.21-pre5 kksymoops for i386/ia64
Automatic decoding of oops on 2.5 has been very useful, so this patch adds kksymoops support to 2.4.21-pre5. Currently only for i386 and ia64, other architectures are easy to add.
Index: 21-pre5.1/kernel/module.c
kernel/module.c Mon, 17 Mar 2003 17:22:39 +1100 kaos (linux-2.4/j/45_module.c 1.1.2.1.3.1.3.1.1.1.2.2 644) renamed from kernel/module.c Wed, 11 Dec 2002 11:38:55 +1100 kaos (linux-2.4/j/45_module.c 1.1.2.1.3.1.3.1.1.1.2.2 644) +102 -0
@@ -3,6 +3,7 @@ #include <linux/module.h> #include <asm/module.h> #include <asm/uaccess.h> +#include <linux/kallsyms.h> #include <linux/vmalloc.h> #include <linux/smp_lock.h> #include <asm/pgalloc.h>
@@ -1235,6 +1236,30 @@ struct seq_operations ksyms_op = { show: s_show }; +#define MODLIST_SIZE 4096 + +/* + * this function isn't smp safe but that's not really a problem; it's + * called from oops context only and any locking could actually prevent + * the oops from going out; the line that is generated is informational + * only and should NEVER prevent the real oops from going out. + */ +void print_modules(void) +{ + static char modlist[MODLIST_SIZE]; + struct module *this_mod; + int pos = 0; + + this_mod = module_list; + while (this_mod) { + if (this_mod->name) + pos += snprintf(modlist+pos, MODLIST_SIZE-pos-1, + "%s ", this_mod->name); + this_mod = this_mod->next; + } + printk("%s\n",modlist); +} + #else /* CONFIG_MODULES */ /* Dummy syscalls for people who don't want modules */
@@ -1280,4 +1305,81 @@ int try_inc_mod_count(struct module *mod return 1; } +void print_modules(void) +{ +} + #endif /* CONFIG_MODULES */ + + +#if defined(CONFIG_MODULES) || defined(CONFIG_KALLSYMS) + +#define MAX_SYMBOL_SIZE 512 + +static void +address_to_exported_symbol(unsigned long address, const char **mod_name, + const char **sym_name, unsigned long *sym_start, + unsigned long *sym_end) +{ + struct module *this_mod; + int i; + + for (this_mod = module_list; this_mod; this_mod = this_mod->next) { + /* walk the symbol list of this module. Only symbols + who's address is smaller than the searched for address + are relevant; and only if it's better than the best so far */ + for (i = 0; i < this_mod->nsyms; i++) + if ((this_mod->syms[i].value <= address) && + (*sym_start < this_mod->syms[i].value)) { + *sym_start = this_mod->syms[i].value; + *sym_name = this_mod->syms[i].name; + *mod_name = this_mod->name; + if (i + 1 < this_mod->nsyms) + *sym_end = this_mod->syms[i+1].value; + else + *sym_end = (unsigned long) this_mod + this_mod->size; + } + } +} + +void +print_symbol(const char *fmt, unsigned long address) +{ + /* static to not take up stackspace; if we race here too bad */ + static char buffer[MAX_SYMBOL_SIZE]; + + const char *mod_name = NULL, *sec_name = NULL, *sym_name = NULL; + unsigned long mod_start, mod_end, sec_start, sec_end, + sym_start, sym_end; + char *tag = ""; + + memset(buffer, 0, MAX_SYMBOL_SIZE); + + sym_start = 0; + if (!kallsyms_address_to_symbol(address, &mod_name, &mod_start, &mod_end, &sec_name, &sec_start, &sec_end, &sym_name, &sym_start, &sym_end)) { + tag = "E "; + address_to_exported_symbol(address, &mod_name, &sym_name, &sym_start, &sym_end); + } + + if (sym_start) { + if (*mod_name) + snprintf(buffer, MAX_SYMBOL_SIZE - 1, "%s%s+%#x/%#x [%s]", + tag, sym_name, + (unsigned int)(address - sym_start), + (unsigned int)(sym_end - sym_start), + mod_name); + else + snprintf(buffer, MAX_SYMBOL_SIZE - 1, "%s%s+%#x/%#x", + tag, sym_name, + (unsigned int)(address - sym_start), + (unsigned int)(sym_end - sym_start)); + printk(fmt, buffer); + } +#if 0 + else { + printk(fmt, "[unresolved]"); + } +#endif +} + +#endif
Index: 21-pre5.1/kernel/ksyms.c
kernel/ksyms.c Mon, 17 Mar 2003 17:42:52 +1100 kaos (linux-2.4/j/46_ksyms.c 1.1.2.2.1.1.2.1.1.8.2.1.2.1.1.4.1.39 644) renamed from kernel/ksyms.c Thu, 27 Feb 2003 19:36:53 +1100 kaos (linux-2.4/j/46_ksyms.c 1.1.2.2.1.1.2.1.1.8.2.1.2.1.1.4.1.39 644) +12 -0
@@ -56,6 +56,9 @@ #ifdef CONFIG_KMOD #include <linux/kmod.h> #endif +#ifdef CONFIG_KALLSYMS +#include <linux/kallsyms.h> +#endif extern void set_device_ro(kdev_t dev,int flag);
@@ -81,6 +84,15 @@ EXPORT_SYMBOL(inter_module_get_request); EXPORT_SYMBOL(inter_module_put); EXPORT_SYMBOL(try_inc_mod_count); +#ifdef CONFIG_KALLSYMS +extern const char __start___kallsyms[]; +extern const char __stop___kallsyms[]; +EXPORT_SYMBOL(__start___kallsyms); +EXPORT_SYMBOL(__stop___kallsyms); +EXPORT_SYMBOL(kallsyms_symbol_to_address); +EXPORT_SYMBOL(kallsyms_address_to_symbol); +#endif + /* process memory management */ EXPORT_SYMBOL(do_mmap_pgoff); EXPORT_SYMBOL(do_munmap);
Index: 21-pre5.1/kernel/Makefile
kernel/Makefile Mon, 17 Mar 2003 18:11:54 +1100 kaos (linux-2.4/k/3_Makefile 1.1.10.2 644) renamed from kernel/Makefile Tue, 18 Sep 2001 13:43:44 +1000 kaos (linux-2.4/k/3_Makefile 1.1.10.2 644) +1 -0
@@ -19,6 +19,7 @@ obj-y = sched.o dma.o fork.o exec_do obj-$(CONFIG_UID16) += uid16.o obj-$(CONFIG_MODULES) += ksyms.o obj-$(CONFIG_PM) += pm.o +obj-$(CONFIG_KALLSYMS) += kallsyms.o ifneq ($(CONFIG_IA64),y) # According to Alan Modra <[email protected]>, the -fno-omit-frame-pointer is
Index: 21-pre5.1/include/linux/module.h
include/linux/module.h Mon, 17 Mar 2003 17:55:02 +1100 kaos (linux-2.4/c/b/46_module.h 1.1.1.1.2.6.1.1.1.2.1.1 644) renamed from include/linux/module.h Thu, 01 Aug 2002 11:23:16 +1000 kaos (linux-2.4/c/b/46_module.h 1.1.1.1.2.6.1.1.1.2.1.1 644) +25 -0
@@ -412,4 +412,29 @@ __attribute__((section("__ksymtab"))) = #define SET_MODULE_OWNER(some_struct) do { } while (0) #endif +extern void print_modules(void); + +#if defined(CONFIG_MODULES) || defined(CONFIG_KALLSYMS) + +extern struct module *module_list; + +/* + * print_symbols takes a format string containing one %s. + * If support for resolving symbols is compiled in, the %s will + * be replaced by the closest symbol to the address and the entire + * string is printk()ed. Otherwise, nothing is printed. + */ +extern void print_symbol(const char *fmt, unsigned long address); + +#else + +#include <linux/errno.h> +static inline int +print_symbol(const char *fmt, unsigned long address) +{ + return -ESRCH; +} + +#endif + #endif /* _LINUX_MODULE_H */
Index: 21-pre5.1/arch/ia64/kernel/process.c
arch/ia64/kernel/process.c Mon, 17 Mar 2003 17:19:58 +1100 kaos (linux-2.4/r/c/50_process.c 1.1.3.1.3.1.2.2.1.2.1.2 644) renamed from arch/ia64/kernel/process.c Thu, 27 Feb 2003 19:36:53 +1100 kaos (linux-2.4/r/c/50_process.c 1.1.3.1.3.1.2.2.1.2.1.2 644) +15 -2
@@ -12,6 +12,7 @@ #include <linux/errno.h> #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/module.h> #include <linux/personality.h> #include <linux/sched.h> #include <linux/slab.h>
@@ -37,8 +38,9 @@ static void do_show_stack (struct unw_frame_info *info, void *arg) { unsigned long ip, sp, bsp; + char buf[80]; /* don't make it so big that it overflows the stack! */ - printk("\nCall Trace: "); + printk("\nCall Trace:\n"); do { unw_get_ip(info, &ip); if (ip = 0)
@@ -46,7 +48,9 @@ do_show_stack (struct unw_frame_info *in unw_get_sp(info, &sp); unw_get_bsp(info, &bsp); - printk("[<%016lx>] sp=0x%016lx bsp=0x%016lx\n", ip, sp, bsp); + snprintf(buf, sizeof(buf), " [<%016lx>] %%s sp=0x%016lx bsp=0x%016lx\n", + ip, sp, bsp); + print_symbol(buf, ip); } while (unw_unwind(info) >= 0); }
@@ -73,13 +77,22 @@ show_stack (struct task_struct *task) } void +dump_stack (void) +{ + show_stack(NULL); +} + +void show_regs (struct pt_regs *regs) { unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri; printk("\nPid: %d, comm: %20s\n", current->pid, current->comm); + printk("Registers: cpu %d, sapicid 0x%04x, time %ld\n", + smp_processor_id(), hard_smp_processor_id(), jiffies); printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s\n", regs->cr_ipsr, regs->cr_ifs, ip, print_tainted()); + print_symbol("ip is at %s\n", ip); printk("unat: %016lx pfs : %016lx rsc : %016lx\n", regs->ar_unat, regs->ar_pfs, regs->ar_rsc); printk("rnat: %016lx bsps: %016lx pr : %016lx\n",
Index: 21-pre5.1/arch/ia64/config.in
arch/ia64/config.in Mon, 17 Mar 2003 17:32:06 +1100 kaos (linux-2.4/s/c/38_config.in 1.1.2.1.2.2.3.1.1.2.1.5 644) renamed from arch/ia64/config.in Sun, 12 Jan 2003 11:14:47 +1100 kaos (linux-2.4/s/c/38_config.in 1.1.2.1.2.2.3.1.1.2.1.5 644) +1 -0
@@ -284,6 +284,7 @@ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; th bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK bool ' Turn on compare-and-exchange bug checking (slow!)' CONFIG_IA64_DEBUG_CMPXCHG bool ' Turn on irq debug checks (slow!)' CONFIG_IA64_DEBUG_IRQ + bool ' Load all symbols for debugging/kksymoops' CONFIG_KALLSYMS fi endmenu
Index: 21-pre5.1/arch/i386/vmlinux.lds
arch/i386/vmlinux.lds Mon, 17 Mar 2003 17:31:24 +1100 kaos (linux-2.4/R/c/35_vmlinux.ld 1.1.4.1.2.1 644) renamed from arch/i386/vmlinux.lds Fri, 11 Jan 2002 15:36:30 +1100 kaos (linux-2.4/R/c/35_vmlinux.ld 1.1.4.1.2.1 644) +4 -0
@@ -28,6 +28,10 @@ SECTIONS __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + __start___kallsyms = .; /* All kernel symbols */ + __kallsyms : { *(__kallsyms) } + __stop___kallsyms = .; + .data : { /* Data */ *(.data) CONSTRUCTORS
Index: 21-pre5.1/arch/i386/kernel/traps.c
arch/i386/kernel/traps.c Mon, 17 Mar 2003 17:19:00 +1100 kaos (linux-2.4/S/c/22_traps.c 1.1.2.1.1.2.1.1.1.12 644) renamed from arch/i386/kernel/traps.c Sun, 18 Aug 2002 23:16:19 +1000 kaos (linux-2.4/S/c/22_traps.c 1.1.2.1.1.2.1.1.1.12 644) +10 -6
@@ -139,15 +139,16 @@ void show_trace(unsigned long * stack) if (!stack) stack = (unsigned long*)&stack; - printk("Call Trace: "); + printk("Call Trace:"); +#if CONFIG_KALLSYMS + printk("\n"); +#endif i = 1; while (((long) stack & (THREAD_SIZE-1)) != 0) { addr = *stack++; if (kernel_text_address(addr)) { - if (i && ((i % 6) = 0)) - printk("\n "); - printk(" [<%08lx>]", addr); - i++; + printk(" [<%08lx>] ", addr); + print_symbol("%s\n", addr); } } printk("\n");
@@ -208,8 +209,11 @@ void show_registers(struct pt_regs *regs esp = regs->esp; ss = regs->xss & 0xffff; } + print_modules(); printk("CPU: %d\nEIP: %04x:[<%08lx>] %s\nEFLAGS: %08lx\n", smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags); + + print_symbol("EIP is at %s\n", regs->eip); printk("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", regs->eax, regs->ebx, regs->ecx, regs->edx); printk("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
@@ -227,7 +231,7 @@ void show_registers(struct pt_regs *regs printk("\nStack: "); show_stack((unsigned long*)esp); - printk("\nCode: "); + printk("Code: "); if(regs->eip < PAGE_OFFSET) goto bad;
Index: 21-pre5.1/arch/i386/config.in
arch/i386/config.in Mon, 17 Mar 2003 17:30:24 +1100 kaos (linux-2.4/T/c/36_config.in 1.1.2.1.2.32 644) renamed from arch/i386/config.in Wed, 29 Jan 2003 16:24:17 +1100 kaos (linux-2.4/T/c/36_config.in 1.1.2.1.2.32 644) +1 -0
@@ -471,6 +471,7 @@ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; th bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK bool ' Compile the kernel with frame pointers' CONFIG_FRAME_POINTER + bool ' Load all symbols for debugging/kksymoops' CONFIG_KALLSYMS fi endmenu
Index: 21-pre5.1/Makefile
Makefile Mon, 17 Mar 2003 17:37:53 +1100 kaos (linux-2.4/T/c/50_Makefile 1.1.2.15.1.2.2.25.2.2.1.17.1.4.1.29.1.40.1.51 644) renamed from Makefile Thu, 27 Feb 2003 19:36:53 +1100 kaos (linux-2.4/T/c/50_Makefile 1.1.2.15.1.2.2.25.2.2.1.17.1.4.1.29.1.40.1.51 644) +35 -9
63 lines not on this page · raw message
Index: 21-pre5.1/Documentation/Configure.help
Documentation/Configure.help Mon, 17 Mar 2003 17:34:52 +1100 kaos (linux-2.4/Z/c/10_Configure. 1.1.2.8.2.10.1.4.2.10.2.71 644) renamed from Documentation/Configure.help Thu, 27 Feb 2003 19:36:53 +1100 kaos (linux-2.4/Z/c/10_Configure. 1.1.2.8.2.10.1.4.2.10.2.71 644) +10 -0
@@ -20554,6 +20554,16 @@ CONFIG_MAGIC_SYSRQ keys are documented in <file:Documentation/sysrq.txt>. Don't say Y unless you really know what this hack does. +Load all symbols for debugging/kksymoops +CONFIG_KALLSYMS + Normally only exported symbols are available to modules. For + debugging you may want all symbols, not just the exported ones. If + you say Y here then extra data is added to the kernel and modules, + this data lists all the non-stack symbols in the kernel or module + and can be used by any debugger. You need modutils >= 2.3.11 to use + this option. See "man kallsyms" for the data format, it adds 10-20% + to the size of the kernel and the loaded modules. If unsure, say N. + ISDN support CONFIG_ISDN ISDN ("Integrated Services Digital Networks", called RNIS in France)
Index: 21-pre5.1/include/linux/kallsyms.h
include/linux/kallsyms.h Mon, 17 Mar 2003 17:55:02 +1100 kaos (linux-2.4/R/g/44_kallsyms.h 644) renamed from include/linux/kallsyms.h Mon, 17 Mar 2003 18:15:52 +1100 kaos () +169 -0
169 lines not on this page · raw message
Index: 21-pre5.1/kernel/kallsyms.c
kernel/kallsyms.c Mon, 17 Mar 2003 17:48:59 +1100 kaos (linux-2.4/R/g/45_kallsyms.c 644) renamed from kernel/kallsyms.c Mon, 17 Mar 2003 18:15:52 +1100 kaos () +418 -0
418 lines not on this page · raw message