[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86: Better BUG() and ASSERT() logging.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1172068837 0
# Node ID 43e9952b07ea6e92306a224ac259a440fe9d4891
# Parent  bca284f67702cf46502809f29eb634e2ab6d294f
x86: Better BUG() and ASSERT() logging.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/extable.c           |   13 +----
 xen/arch/x86/traps.c             |   95 +++++++++++++++++++++++++++------------
 xen/include/asm-x86/bug.h        |   12 ++++
 xen/include/asm-x86/x86_32/bug.h |   27 +++++++----
 xen/include/asm-x86/x86_64/bug.h |   27 +++++++----
 xen/include/xen/lib.h            |   22 ++++-----
 6 files changed, 128 insertions(+), 68 deletions(-)

diff -r bca284f67702 -r 43e9952b07ea xen/arch/x86/extable.c
--- a/xen/arch/x86/extable.c    Wed Feb 21 10:13:40 2007 +0000
+++ b/xen/arch/x86/extable.c    Wed Feb 21 14:40:37 2007 +0000
@@ -1,13 +1,8 @@
 
 #include <xen/config.h>
+#include <xen/perfc.h>
 #include <xen/spinlock.h>
 #include <asm/uaccess.h>
-
-#ifdef PERF_COUNTERS
-#include <xen/sched.h>
-#include <xen/perfc.h>
-#include <asm/current.h>
-#endif
 
 extern struct exception_table_entry __start___ex_table[];
 extern struct exception_table_entry __stop___ex_table[];
@@ -74,10 +69,10 @@ search_pre_exception_table(struct cpu_us
     unsigned long addr = (unsigned long)regs->eip;
     unsigned long fixup = search_one_table(
         __start___pre_ex_table, __stop___pre_ex_table-1, addr);
-    dprintk(XENLOG_INFO, "Pre-exception: %p -> %p\n", _p(addr), _p(fixup));
-#ifdef PERF_COUNTERS
     if ( fixup )
+    {
+        dprintk(XENLOG_INFO, "Pre-exception: %p -> %p\n", _p(addr), _p(fixup));
         perfc_incrc(exception_fixed);
-#endif
+    }
     return fixup;
 }
diff -r bca284f67702 -r 43e9952b07ea xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Wed Feb 21 10:13:40 2007 +0000
+++ b/xen/arch/x86/traps.c      Wed Feb 21 14:40:37 2007 +0000
@@ -618,40 +618,77 @@ static int emulate_forced_invalid_op(str
 
 asmlinkage int do_invalid_op(struct cpu_user_regs *regs)
 {
-    int rc;
+    struct bug_frame bug;
+    struct bug_frame_str bug_str;
+    char *filename, *predicate, *eip = (char *)regs->eip;
+    int rc, id, lineno;
 
     DEBUGGER_trap_entry(TRAP_invalid_op, regs);
 
-    if ( unlikely(!guest_mode(regs)) )
-    {
-        struct bug_frame bug;
-        if ( is_kernel(regs->eip) &&
-             (__copy_from_user(&bug, (char *)regs->eip, sizeof(bug)) == 0) &&
-             (memcmp(bug.ud2, "\xf\xb",    sizeof(bug.ud2)) == 0) &&
-             (memcmp(bug.mov, BUG_MOV_STR, sizeof(bug.mov)) == 0) &&
-             (bug.ret == 0xc2) )
-        {
-            char *filename = (char *)bug.filename;
-            unsigned int line = bug.line & 0x7fff;
-            int is_bug = !(bug.line & 0x8000);
-            printk("Xen %s at %.50s:%d\n",
-                   is_bug ? "BUG" : "State Dump", filename, line);
-            if ( !is_bug )
-            {
-                show_execution_state(regs);
-                regs->eip += sizeof(bug);
-                return EXCRET_fault_fixed;
-            }
-        }
+    if ( likely(guest_mode(regs)) )
+    {
+        if ( (rc = emulate_forced_invalid_op(regs)) != 0 )
+            return rc;
+        return do_guest_trap(TRAP_invalid_op, regs, 0);
+    }
+
+    if ( !is_kernel(eip) ||
+         __copy_from_user(&bug, eip, sizeof(bug)) ||
+         memcmp(bug.ud2, "\xf\xb", sizeof(bug.ud2)) ||
+         (bug.ret != 0xc2) )
+        goto die;
+
+    id = bug.id & 3;
+    if ( id == BUGFRAME_rsvd )
+        goto die;
+
+    if ( id == BUGFRAME_dump )
+    {
+        show_execution_state(regs);
+        regs->eip += sizeof(bug);
+        return EXCRET_fault_fixed;
+    }
+
+    /* BUG() or ASSERT(): decode the filename pointer and line number. */
+    ASSERT((id == BUGFRAME_bug) || (id == BUGFRAME_assert));
+    eip += sizeof(bug);
+    if ( !is_kernel(eip) ||
+         __copy_from_user(&bug_str, eip, sizeof(bug_str)) ||
+         memcmp(bug_str.mov, BUG_MOV_STR, sizeof(bug_str.mov)) )
+        goto die;
+
+    filename = is_kernel(bug_str.str) ? (char *)bug_str.str : "<unknown>";
+    lineno   = bug.id >> 2;
+
+    if ( id == BUGFRAME_bug )
+    {
+        printk("Xen BUG at %.50s:%d\n", filename, lineno);
         DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
         show_execution_state(regs);
-        panic("FATAL TRAP: vector = %d (invalid opcode)\n", TRAP_invalid_op);
-    }
-
-    if ( (rc = emulate_forced_invalid_op(regs)) != 0 )
-        return rc;
-
-    return do_guest_trap(TRAP_invalid_op, regs, 0);
+        panic("Xen BUG at %.50s:%d\n", filename, lineno);
+    }
+
+    /* ASSERT(): decode the predicate string pointer. */
+    ASSERT(id == BUGFRAME_assert);
+    eip += sizeof(bug_str);
+    if ( !is_kernel(eip) ||
+         __copy_from_user(&bug_str, eip, sizeof(bug_str)) ||
+         memcmp(bug_str.mov, BUG_MOV_STR, sizeof(bug_str.mov)) )
+        goto die;
+
+    predicate = is_kernel(bug_str.str) ? (char *)bug_str.str : "<unknown>";
+    printk("Assertion '%s' failed at %.50s:%d\n",
+           predicate, filename, lineno);
+    DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
+    show_execution_state(regs);
+    panic("Assertion '%s' failed at %.50s:%d\n",
+          predicate, filename, lineno);
+
+ die:
+    DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
+    show_execution_state(regs);
+    panic("FATAL TRAP: vector = %d (invalid opcode)\n", TRAP_invalid_op);
+    return 0;
 }
 
 asmlinkage int do_int3(struct cpu_user_regs *regs)
diff -r bca284f67702 -r 43e9952b07ea xen/include/asm-x86/bug.h
--- a/xen/include/asm-x86/bug.h Wed Feb 21 10:13:40 2007 +0000
+++ b/xen/include/asm-x86/bug.h Wed Feb 21 14:40:37 2007 +0000
@@ -7,7 +7,15 @@
 #include <asm/x86_32/bug.h>
 #endif
 
-#define BUG()                  __BUG(__FILE__, __LINE__)
-#define dump_execution_state() __BUG(__FILE__, __LINE__ | 0x8000)
+struct bug_frame {
+    unsigned char ud2[2];
+    unsigned char ret;
+    unsigned short id; /* BUGFRAME_??? */
+} __attribute__((packed));
+
+#define BUGFRAME_dump   0
+#define BUGFRAME_bug    1
+#define BUGFRAME_assert 2
+#define BUGFRAME_rsvd   3
 
 #endif /* __X86_BUG_H__ */
diff -r bca284f67702 -r 43e9952b07ea xen/include/asm-x86/x86_32/bug.h
--- a/xen/include/asm-x86/x86_32/bug.h  Wed Feb 21 10:13:40 2007 +0000
+++ b/xen/include/asm-x86/x86_32/bug.h  Wed Feb 21 14:40:37 2007 +0000
@@ -1,19 +1,28 @@
 #ifndef __X86_32_BUG_H__
 #define __X86_32_BUG_H__
 
-struct bug_frame {
-    unsigned char ud2[2];
+struct bug_frame_str {
     unsigned char mov[1];
-    unsigned long filename;
-    unsigned char ret;
-    unsigned short line;
+    unsigned long str;
 } __attribute__((packed));
-
 #define BUG_MOV_STR "\xbc"
 
-#define __BUG(file, line)                               \
+#define dump_execution_state()                          \
     asm volatile (                                      \
-        "ud2 ; .byte 0xbc ; .long %c1 ; ret $%c0"       \
-        : : "i" (line), "i" (file) )
+        "ud2 ; ret $%c0"                                \
+        : : "i" (BUGFRAME_dump) )
+
+#define BUG()                                           \
+    asm volatile (                                      \
+        "ud2 ; ret $%c0 ; .byte 0xbc ; .long %c1"       \
+        : : "i" (BUGFRAME_bug | (__LINE__<<2)),         \
+            "i" (__FILE__) )
+
+#define assert_failed(p)                                \
+    asm volatile (                                      \
+        "ud2 ; ret $%c0 ; .byte 0xbc ; .long %c1"       \
+        " ; .byte 0xbc ; .long %c2"                     \
+        : : "i" (BUGFRAME_assert | (__LINE__<<2)),      \
+            "i" (__FILE__), "i" (#p) )
 
 #endif /* __X86_32_BUG_H__ */
diff -r bca284f67702 -r 43e9952b07ea xen/include/asm-x86/x86_64/bug.h
--- a/xen/include/asm-x86/x86_64/bug.h  Wed Feb 21 10:13:40 2007 +0000
+++ b/xen/include/asm-x86/x86_64/bug.h  Wed Feb 21 14:40:37 2007 +0000
@@ -1,19 +1,28 @@
 #ifndef __X86_64_BUG_H__
 #define __X86_64_BUG_H__
 
-struct bug_frame {
-    unsigned char ud2[2];
+struct bug_frame_str {
     unsigned char mov[2];
-    unsigned long filename;
-    unsigned char ret;
-    unsigned short line;
+    unsigned long str;
 } __attribute__((packed));
-
 #define BUG_MOV_STR "\x48\xbc"
 
-#define __BUG(file, line)                               \
+#define dump_execution_state()                          \
     asm volatile (                                      \
-        "ud2 ; .byte 0x48,0xbc ; .quad %c1 ; ret $%c0"  \
-        : : "i" (line), "i" (file) )
+        "ud2 ; ret $%c0"                                \
+        : : "i" (BUGFRAME_dump) )
+
+#define BUG()                                           \
+    asm volatile (                                      \
+        "ud2 ; ret $%c0 ; .byte 0x48,0xbc ; .quad %c1"  \
+        : : "i" (BUGFRAME_bug | (__LINE__<<2)),         \
+            "i" (__FILE__) )
+
+#define assert_failed(p)                                \
+    asm volatile (                                      \
+        "ud2 ; ret $%c0 ; .byte 0x48,0xbc ; .quad %c1"  \
+        " ; .byte 0x48,0xbc ; .quad %c2"                \
+        : : "i" (BUGFRAME_assert | (__LINE__<<2)),      \
+            "i" (__FILE__), "i" (#p) )
 
 #endif /* __X86_64_BUG_H__ */
diff -r bca284f67702 -r 43e9952b07ea xen/include/xen/lib.h
--- a/xen/include/xen/lib.h     Wed Feb 21 10:13:40 2007 +0000
+++ b/xen/include/xen/lib.h     Wed Feb 21 14:40:37 2007 +0000
@@ -16,18 +16,20 @@ void __bug(char *file, int line) __attri
 /* Force a compilation error if condition is true */
 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
 
+#ifndef assert_failed
+#define assert_failed(p)                                        \
+do {                                                            \
+    printk("Assertion '%s' failed, line %d, file %s\n", #p ,    \
+                   __LINE__, __FILE__);                         \
+    BUG();                                                      \
+} while (0)
+#endif
+
 #ifndef NDEBUG
-#define ASSERT(_p)                                                      \
-    do {                                                                \
-        if ( unlikely(!(_p)) )                                          \
-        {                                                               \
-            printk("Assertion '%s' failed, line %d, file %s\n", #_p ,   \
-                   __LINE__, __FILE__);                                 \
-            BUG();                                                      \
-        }                                                               \
-    } while ( 0 )
+#define ASSERT(p) \
+    do { if ( unlikely(!(p)) ) assert_failed(p); } while (0)
 #else
-#define ASSERT(_p) ((void)0)
+#define ASSERT(p) ((void)0)
 #endif
 
 #define SWAP(_a, _b) \

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.