Author: mdf
Date: Fri Mar 25 18:16:36 2011
New Revision: 220002
URL: http://svn.freebsd.org/changeset/base/220002

Log:
  MFC r218825.  [The implementation change to kdb_sysctl_available()
  cannot be MFC'd as it requires a non-MFCable change (adding drains to
  sbuf)].
  
  Modify kdb_trap() so that it re-calls the dbbe_trap function as long as
  the debugger back-end has changed.  This means that switching from ddb
  to gdb no longer requires a "step" which can be dangerous on an
  already-crashed kernel.
  
  Also add a capability to get from the gdb back-end back to ddb, by
  typing ^C in the console window.
  
  While here, simplify kdb_sysctl_available() by using
  sbuf_new_for_sysctl(), and use strlcpy() instead of strncpy() since the
  strlcpy semantic is desired.

Modified:
  stable/8/sys/ddb/db_command.c
  stable/8/sys/gdb/gdb_main.c
  stable/8/sys/gdb/gdb_packet.c
  stable/8/sys/kern/subr_kdb.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/ddb/db_command.c
==============================================================================
--- stable/8/sys/ddb/db_command.c       Fri Mar 25 16:38:10 2011        
(r220001)
+++ stable/8/sys/ddb/db_command.c       Fri Mar 25 18:16:36 2011        
(r220002)
@@ -723,10 +723,16 @@ static void
 db_gdb(db_expr_t dummy1, boolean_t dummy2, db_expr_t dummy3, char *dummy4)
 {
 
-       if (kdb_dbbe_select("gdb") != 0)
+       if (kdb_dbbe_select("gdb") != 0) {
                db_printf("The remote GDB backend could not be selected.\n");
-       else
-               db_printf("Step to enter the remote GDB backend.\n");
+               return;
+       }
+       /*
+        * Mark that we are done in the debugger.  kdb_trap()
+        * should re-enter with the new backend.
+        */
+       db_cmd_loop_done = 1;
+       db_printf("(ctrl-c will return control to ddb)\n");
 }
 
 static void

Modified: stable/8/sys/gdb/gdb_main.c
==============================================================================
--- stable/8/sys/gdb/gdb_main.c Fri Mar 25 16:38:10 2011        (r220001)
+++ stable/8/sys/gdb/gdb_main.c Fri Mar 25 18:16:36 2011        (r220002)
@@ -95,7 +95,17 @@ gdb_init(void)
 static int
 gdb_trap(int type, int code)
 {
+       jmp_buf jb;
        struct thread *thr_iter;
+       void *prev_jb;
+
+       prev_jb = kdb_jmpbuf(jb);
+       if (setjmp(jb) != 0) {
+               printf("%s bailing, hopefully back to ddb!\n", __func__);
+               gdb_listening = 0;
+               (void)kdb_jmpbuf(prev_jb);
+               return (1);
+       }
 
        gdb_listening = 0;
        /*
@@ -291,5 +301,6 @@ gdb_trap(int type, int code)
                        break;
                }
        }
+       (void)kdb_jmpbuf(prev_jb);
        return (0);
 }

Modified: stable/8/sys/gdb/gdb_packet.c
==============================================================================
--- stable/8/sys/gdb/gdb_packet.c       Fri Mar 25 16:38:10 2011        
(r220001)
+++ stable/8/sys/gdb/gdb_packet.c       Fri Mar 25 18:16:36 2011        
(r220002)
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/ctype.h>
 #include <sys/kdb.h>
+#include <sys/ttydefaults.h>
 
 #include <machine/gdb_machdep.h>
 #include <machine/kdb.h>
@@ -60,6 +61,17 @@ gdb_getc(void)
        do
                c = gdb_cur->gdb_getc();
        while (c == -1);
+
+       if (c == CTRL('C')) {
+               printf("Received ^C; trying to switch back to ddb.\n");
+
+               if (kdb_dbbe_select("ddb") != 0)
+                       printf("The ddb backend could not be selected.\n");
+               else {
+                       printf("using longjmp, hope it works!\n");
+                       kdb_reenter();
+               }
+       }
        return (c);
 }
 

Modified: stable/8/sys/kern/subr_kdb.c
==============================================================================
--- stable/8/sys/kern/subr_kdb.c        Fri Mar 25 16:38:10 2011        
(r220001)
+++ stable/8/sys/kern/subr_kdb.c        Fri Mar 25 18:16:36 2011        
(r220002)
@@ -144,10 +144,9 @@ kdb_sysctl_current(SYSCTL_HANDLER_ARGS)
        char buf[16];
        int error;
 
-       if (kdb_dbbe != NULL) {
-               strncpy(buf, kdb_dbbe->dbbe_name, sizeof(buf));
-               buf[sizeof(buf) - 1] = '\0';
-       } else
+       if (kdb_dbbe != NULL)
+               strlcpy(buf, kdb_dbbe->dbbe_name, sizeof(buf));
+       else
                *buf = '\0';
        error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
        if (error != 0 || req->newptr == NULL)
@@ -513,13 +512,15 @@ kdb_thr_select(struct thread *thr)
 int
 kdb_trap(int type, int code, struct trapframe *tf)
 {
+       struct kdb_dbbe *be;
        register_t intr;
 #ifdef SMP
        int did_stop_cpus;
 #endif
        int handled;
 
-       if (kdb_dbbe == NULL || kdb_dbbe->dbbe_trap == NULL)
+       be = kdb_dbbe;
+       if (be == NULL || be->dbbe_trap == NULL)
                return (0);
 
        /* We reenter the debugger through kdb_reenter(). */
@@ -543,7 +544,15 @@ kdb_trap(int type, int code, struct trap
        makectx(tf, &kdb_pcb);
        kdb_thr_select(curthread);
 
-       handled = kdb_dbbe->dbbe_trap(type, code);
+       for (;;) {
+               handled = be->dbbe_trap(type, code);
+               if (be == kdb_dbbe)
+                       break;
+               be = kdb_dbbe;
+               if (be == NULL || be->dbbe_trap == NULL)
+                       break;
+               printf("Switching to %s back-end\n", be->dbbe_name);
+       }
 
        kdb_active--;
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to