[PATCH] x86_64: Display meaningful part of filename during BUG()
authorJan Beulich <jbeulich@novell.com>
Wed, 11 Jan 2006 21:46:48 +0000 (22:46 +0100)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 12 Jan 2006 03:05:03 +0000 (19:05 -0800)
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>
arch/x86_64/kernel/traps.c
arch/x86_64/lib/usercopy.c
include/asm-x86_64/uaccess.h

index d345c712c6ca192705b2b637768c6532ffc234f1..2671fd46ea8568f3db7944e5f89a91f2e1eff0a5 100644 (file)
@@ -340,7 +340,8 @@ bad:
 void handle_BUG(struct pt_regs *regs)
 { 
        struct bug_frame f;
-       char tmp;
+       long len;
+       const char *prefix = "";
 
        if (user_mode(regs))
                return; 
@@ -350,10 +351,15 @@ void handle_BUG(struct pt_regs *regs)
        if (f.filename >= 0 ||
            f.ud2[0] != 0x0f || f.ud2[1] != 0x0b) 
                return;
-       if (__get_user(tmp, (char *)(long)f.filename))
+       len = __strnlen_user((char *)(long)f.filename, PATH_MAX) - 1;
+       if (len < 0 || len >= PATH_MAX)
                f.filename = (int)(long)"unmapped filename";
+       else if (len > 50) {
+               f.filename += len - 50;
+               prefix = "...";
+       }
        printk("----------- [cut here ] --------- [please bite here ] ---------\n");
-       printk(KERN_ALERT "Kernel BUG at %.50s:%d\n", (char *)(long)f.filename, f.line);
+       printk(KERN_ALERT "Kernel BUG at %s%.50s:%d\n", prefix, (char *)(long)f.filename, f.line);
 } 
 
 #ifdef CONFIG_BUG
index db8abba1ad819901a1a327465cb1d2fe7061cd5f..9bc2c295818e3c2d2faa97ecee0e17a336843b48 100644 (file)
@@ -109,14 +109,11 @@ unsigned long clear_user(void __user *to, unsigned long n)
  * Return 0 on exception, a value greater than N if too long
  */
 
-long strnlen_user(const char __user *s, long n)
+long __strnlen_user(const char __user *s, long n)
 {
        long res = 0;
        char c;
 
-       if (!access_ok(VERIFY_READ, s, n))
-               return 0;
-
        while (1) {
                if (res>n)
                        return n+1;
@@ -129,6 +126,13 @@ long strnlen_user(const char __user *s, long n)
        }
 }
 
+long strnlen_user(const char __user *s, long n)
+{
+       if (!access_ok(VERIFY_READ, s, n))
+               return 0;
+       return __strnlen_user(s, n);
+}
+
 long strlen_user(const char __user *s)
 {
        long res = 0;
index 1bb8b8a24436b2387a348b8d0ae880e14d61c6c6..2892c4b7a28b01769bd25c88b7a5e9065e7e8a15 100644 (file)
@@ -348,6 +348,7 @@ static inline int __copy_in_user(void __user *dst, const void __user *src, unsig
 long strncpy_from_user(char *dst, const char __user *src, long count);
 long __strncpy_from_user(char *dst, const char __user *src, long count);
 long strnlen_user(const char __user *str, long n);
+long __strnlen_user(const char __user *str, long n);
 long strlen_user(const char __user *str);
 unsigned long clear_user(void __user *mem, unsigned long len);
 unsigned long __clear_user(void __user *mem, unsigned long len);