Ingo Molnar wrote:
(gdb) #################################### (gdb) # c013ebf4, stack size: 388 bytes # (gdb) #################################### (gdb) 0xc013ebf4 is in __print_symbol (kernel/kallsyms.c:234).
The attached patch fixes this partially by reducing the stack usage by 128 bytes. Compile, boot and run tested and apparently it works fine. I didn't want to use kmalloc's in there because this function is probably called from very "hard" contexts (kernel OOPS, stack overflow dumps, etc.). The stack usage could be reduced even further (I can do a patch for this if needed) by changing the function to receive a "prefix" and a "suffix" string instead of a format string. The function could then simply do: printk(prefix); printk(symbol); printk(address); if (module) printk(module name); printk(suffix); This way it wouldn't need to allocate a buffer big enough for the whole string, just for one symbol name (128 bytes). This is a much more intrusive change however (there are ~65 callers that would need changing), so I leave the decision to more experienced hackers :) -- Paulo Marques - www.grupopie.com It is a mistake to think you can solve any major problems just with potatoes. Douglas Adams
--- ./kernel/kallsyms.c.orig 2005-07-11 12:32:32.000000000 +0100 +++ ./kernel/kallsyms.c 2005-07-11 12:34:42.000000000 +0100 @@ -232,23 +232,21 @@ const char *kallsyms_lookup(unsigned lon /* Replace "%s" in format with address, or returns -errno. */ void __print_symbol(const char *fmt, unsigned long address) { - char *modname; + char *modname, *bufend; const char *name; unsigned long offset, size; - char namebuf[KSYM_NAME_LEN+1]; char buffer[sizeof("%s+%#lx/%#lx [%s]") + KSYM_NAME_LEN + 2*(BITS_PER_LONG*3/10) + MODULE_NAME_LEN + 1]; - name = kallsyms_lookup(address, &size, &offset, &modname, namebuf); + name = kallsyms_lookup(address, &size, &offset, &modname, buffer); if (!name) sprintf(buffer, "0x%lx", address); else { + bufend = strchr(buffer, '\0'); + bufend += sprintf(bufend, "+%#lx/%#lx", offset, size); if (modname) - sprintf(buffer, "%s+%#lx/%#lx [%s]", name, offset, - size, modname); - else - sprintf(buffer, "%s+%#lx/%#lx", name, offset, size); + sprintf(bufend, " [%s]", modname); } printk(fmt, buffer); }