[PATCH] x86_64: Display meaningful part of filename during BUG()

When building in a separate objtree, file names produced by BUG() & Co. can
get fairly long; printing only the first 50 characters may thus result in
(almost) no useful information. The following change makes it so that rather
the last 50 characters of the filename get printed.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Jan Beulich and committed by Linus Torvalds 5f1d189f 1b2f6304

+18 -7
+9 -3
arch/x86_64/kernel/traps.c
··· 340 340 void handle_BUG(struct pt_regs *regs) 341 341 { 342 342 struct bug_frame f; 343 - char tmp; 343 + long len; 344 + const char *prefix = ""; 344 345 345 346 if (user_mode(regs)) 346 347 return; ··· 351 350 if (f.filename >= 0 || 352 351 f.ud2[0] != 0x0f || f.ud2[1] != 0x0b) 353 352 return; 354 - if (__get_user(tmp, (char *)(long)f.filename)) 353 + len = __strnlen_user((char *)(long)f.filename, PATH_MAX) - 1; 354 + if (len < 0 || len >= PATH_MAX) 355 355 f.filename = (int)(long)"unmapped filename"; 356 + else if (len > 50) { 357 + f.filename += len - 50; 358 + prefix = "..."; 359 + } 356 360 printk("----------- [cut here ] --------- [please bite here ] ---------\n"); 357 - printk(KERN_ALERT "Kernel BUG at %.50s:%d\n", (char *)(long)f.filename, f.line); 361 + printk(KERN_ALERT "Kernel BUG at %s%.50s:%d\n", prefix, (char *)(long)f.filename, f.line); 358 362 } 359 363 360 364 #ifdef CONFIG_BUG
+8 -4
arch/x86_64/lib/usercopy.c
··· 109 109 * Return 0 on exception, a value greater than N if too long 110 110 */ 111 111 112 - long strnlen_user(const char __user *s, long n) 112 + long __strnlen_user(const char __user *s, long n) 113 113 { 114 114 long res = 0; 115 115 char c; 116 - 117 - if (!access_ok(VERIFY_READ, s, n)) 118 - return 0; 119 116 120 117 while (1) { 121 118 if (res>n) ··· 124 127 res++; 125 128 s++; 126 129 } 130 + } 131 + 132 + long strnlen_user(const char __user *s, long n) 133 + { 134 + if (!access_ok(VERIFY_READ, s, n)) 135 + return 0; 136 + return __strnlen_user(s, n); 127 137 } 128 138 129 139 long strlen_user(const char __user *s)
+1
include/asm-x86_64/uaccess.h
··· 348 348 long strncpy_from_user(char *dst, const char __user *src, long count); 349 349 long __strncpy_from_user(char *dst, const char __user *src, long count); 350 350 long strnlen_user(const char __user *str, long n); 351 + long __strnlen_user(const char __user *str, long n); 351 352 long strlen_user(const char __user *str); 352 353 unsigned long clear_user(void __user *mem, unsigned long len); 353 354 unsigned long __clear_user(void __user *mem, unsigned long len);