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

Re: [Xen-devel] [RESEND] [PATCH] Use GDB 'O' packets for console output



On Tue, Sep 19, 2006 at 08:27:09AM +0100, Keir Fraser wrote:
Hi Kier,
        Sorry for the delay in my reply.

> Sharing a single serial line between console and gdbstub isn't a mode we
> particularly considered.

It's needed when you only have one functional serial port.

>                          Without something like this patch, I suppose
> ordinary console output and gdb packets get mixed together on the line and
> confuse the gdb session? 

Yup.

>                          Does gdb actually print out the console data with
> your patch?

Sure does.  for example:

(gdb) target remote | ~/bin/gdb-remote
Remote debugging using | ~/bin/gdb-remote
__start_xen (mbi=0x74a430) at setup.c:336
336         if (opt_nosmp || ofd_boot_cpu == -1) {
(gdb) b domctl.c:getdomaininfo
Breakpoint 1 at 0x4020f8: file domctl.c, line 85.
(gdb) c
Continuing.
(XEN) spinning up at most 16 total processors ...
...
<snip> xen and dom0 boot output
...
Blade4 login: (XEN) Waiting for GDB to attach...

Breakpoint 1, getdomaininfo (d=0xa080, info=0xfad8) at domctl.c:85
85          u64 cpu_time = 0;
(gdb)
 
> It's not nice to tell core serial code about the debugger. The switch
> between raw output and output-via-gdbstub should be entirely in console.c.

Attached is a patch that doesn't touch the serial layer at all, and also
compiles on x86/ia64.

---
From: Tony Breeds <tony@xxxxxxxxxxxxxxxxxx>

Use GDB 'O' packets for console output if the serial line is shared and GDB is 
attached.

It may be necessary for gdb and the console to share a serial port.
This patch utilises the GDB protocol to encode console output.

Feedback greatly appreciated.

Signed-off-by: Tony Breeds <tony@xxxxxxxxxxxxxxxxxx>
---
Compiled on x86_32/ia64 (with various values of debug= and crash_debug=)
Tested on PPC

 xen/common/gdbstub.c               |   26 +++++++++++++++++++++++++-
 xen/drivers/char/console.c         |   27 ++++++++++++++++++++++-----
 xen/include/asm-ia64/debugger.h    |    3 +++
 xen/include/asm-powerpc/debugger.h |    3 +++
 xen/include/asm-x86/debugger.h     |    4 ++++
 xen/include/xen/console.h          |    3 +++
 xen/include/xen/gdbstub.h          |    2 ++
 7 files changed, 62 insertions(+), 6 deletions(-)
---
diff -r 7a20fed8be73 xen/common/gdbstub.c
--- a/xen/common/gdbstub.c      Sat Sep 16 09:34:26 2006 -0400
+++ b/xen/common/gdbstub.c      Thu Sep 21 13:04:27 2006 +1000
@@ -470,6 +470,28 @@ __gdb_ctx = {
 };
 static struct gdb_context *gdb_ctx = &__gdb_ctx;
 
+void
+debugger_puts(const char *str)
+{
+    char *p;
+
+    gdb_start_packet(gdb_ctx);
+    gdb_write_to_packet_char('O', gdb_ctx);
+
+    for(p=(char *)str; *p != '\x0'; p++) {
+        gdb_write_to_packet_char(hex2char((*p>>4) & 0x0f), gdb_ctx );
+        gdb_write_to_packet_char(hex2char((*p) & 0x0f), gdb_ctx );
+    }
+
+    gdb_send_packet(gdb_ctx);
+}
+
+int
+in_debugger(void)
+{
+    return gdb_ctx->currently_attached;
+}
+
 /* trap handler: main entry point */
 int 
 __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
@@ -560,8 +582,10 @@ initialise_gdb(void)
 initialise_gdb(void)
 {
     gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
-    if ( gdb_ctx->serhnd != -1 )
+    if ( gdb_ctx->serhnd != -1 ) {
+        console_enable_debugger_io(gdb_ctx->serhnd);
         printk("GDB stub initialised.\n");
+    }
     serial_start_sync(gdb_ctx->serhnd);
 }
 
diff -r 7a20fed8be73 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c        Sat Sep 16 09:34:26 2006 -0400
+++ b/xen/drivers/char/console.c        Thu Sep 21 13:04:27 2006 +1000
@@ -27,6 +27,8 @@
 #include <asm/debugger.h>
 #include <asm/io.h>
 
+/* If a debugger is attached send console output to it */
+static int use_debugger_io = 0;
 /* console: comma-separated list of console outputs. */
 static char opt_console[30] = OPT_CONSOLE_STR;
 string_param("console", opt_console);
@@ -116,6 +118,14 @@ static char serial_rx_ring[SERIAL_RX_SIZ
 static char serial_rx_ring[SERIAL_RX_SIZE];
 static unsigned int serial_rx_cons, serial_rx_prod;
 
+/* Enable debugger output on the serial console if it's the same
+ * port as the debugger */
+void console_enable_debugger_io(int debugger_handle)
+{
+    if ( debugger_handle != -1 && debugger_handle == sercon_handle )
+            use_debugger_io = 1;
+}
+
 /* CTRL-<switch_char> switches input direction between Xen and DOM0. */
 #define SWITCH_CODE (opt_conswitch[0]-'a'+1)
 static int xen_rx = 1; /* FALSE => serial input passed to domain 0. */
@@ -191,11 +201,14 @@ static long guest_console_write(XEN_GUES
             return -EFAULT;
         kbuf[kcount] = '\0';
 
-        serial_puts(sercon_handle, kbuf);
-
-        for ( kptr = kbuf; *kptr != '\0'; kptr++ )
-            vga_putchar(*kptr);
-
+        if ( use_debugger_io && in_debugger() )
+            debugger_puts(kbuf);
+        else {
+            serial_puts(sercon_handle, kbuf);
+
+            for ( kptr = kbuf; *kptr != '\0'; kptr++ )
+                vga_putchar(*kptr);
+        }
         guest_handle_add_offset(buffer, kcount);
         count -= kcount;
     }
@@ -257,6 +270,10 @@ static inline void __putstr(const char *
 {
     int c;
 
+    if ( use_debugger_io && in_debugger() ) {
+        debugger_puts(str);
+        return;
+    }
     serial_puts(sercon_handle, str);
 
     while ( (c = *str++) != '\0' )
diff -r 7a20fed8be73 xen/include/asm-ia64/debugger.h
--- a/xen/include/asm-ia64/debugger.h   Sat Sep 16 09:34:26 2006 -0400
+++ b/xen/include/asm-ia64/debugger.h   Thu Sep 21 13:04:27 2006 +1000
@@ -111,6 +111,9 @@ static inline int debugger_trap_fatal(
 }
 
 #define debugger_trap_immediate()              ((void)0)
+
+#define debugger_puts(str)    ((void)0)
+#define in_debugger()   (0)
 #endif
 #endif // __ASSEMBLLY__
 
diff -r 7a20fed8be73 xen/include/asm-powerpc/debugger.h
--- a/xen/include/asm-powerpc/debugger.h        Sat Sep 16 09:34:26 2006 -0400
+++ b/xen/include/asm-powerpc/debugger.h        Thu Sep 21 13:04:27 2006 +1000
@@ -54,6 +54,9 @@ static inline void debugger_trap_immedia
     show_backtrace(sp, lr, lr);
 }
 
+#define debugger_puts(str)    ((void)0)
+#define in_debugger()   (0)
+
 #endif /* CRASH_DEBUG */
 
 #endif
diff -r 7a20fed8be73 xen/include/asm-x86/debugger.h
--- a/xen/include/asm-x86/debugger.h    Sat Sep 16 09:34:26 2006 -0400
+++ b/xen/include/asm-x86/debugger.h    Thu Sep 21 13:04:27 2006 +1000
@@ -102,6 +102,10 @@ static inline int debugger_trap_entry(
 #define debugger_trap_fatal(v, r) (__debugger_trap_fatal(v, r))
 #ifndef debugger_trap_immediate
 #define debugger_trap_immediate() (__debugger_trap_immediate())
+
+#define debugger_puts(str)    ((void)0)
+#define in_debugger()   (0)
+
 #endif
 
 #endif /* __X86_DEBUGGER_H__ */
diff -r 7a20fed8be73 xen/include/xen/console.h
--- a/xen/include/xen/console.h Sat Sep 16 09:34:26 2006 -0400
+++ b/xen/include/xen/console.h Thu Sep 21 13:04:27 2006 +1000
@@ -26,4 +26,7 @@ void console_start_sync(void);
 void console_start_sync(void);
 void console_end_sync(void);
 
+/* Enable debuggger output if the serial console and debugger are on the same 
+ * port */
+void console_enable_debugger_io(int debugger_handle);
 #endif /* __CONSOLE_H__ */
diff -r 7a20fed8be73 xen/include/xen/gdbstub.h
--- a/xen/include/xen/gdbstub.h Sat Sep 16 09:34:26 2006 -0400
+++ b/xen/include/xen/gdbstub.h Thu Sep 21 13:04:27 2006 +1000
@@ -90,6 +90,8 @@ void gdb_arch_exit(struct cpu_user_regs 
 #define SIGTERM         15
 
 void initialise_gdb(void);
+void debugger_puts(const char *str);
+int in_debugger(void);
 
 #else
 


Yours Tony

   linux.conf.au       http://linux.conf.au/ || http://lca2007.linux.org.au/
   Jan 15-20 2007      The Australian Linux Technical Conference!


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


 


Rackspace

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