Author: rwatson
Date: Fri Aug 26 21:46:36 2011
New Revision: 225203
URL: http://svn.freebsd.org/changeset/base/225203

Log:
  Attempt to make break-to-debugger and alternative break-to-debugger more
  accessible:
  
  (1) Always compile in support for breaking into the debugger if options
      KDB is present in the kernel.
  
  (2) Disable both by default, but allow them to be enabled via tunables
      and sysctls debug.kdb.break_to_debugger and
      debug.kdb.alt_break_to_debugger.
  
  (3) options BREAK_TO_DEBUGGER and options ALT_BREAK_TO_DEBUGGER continue
      to behave as before -- only now instead of compiling in
      break-to-debugger support, they change the default values of the
      above sysctls to enable those features by default.  Current kernel
      configurations should, therefore, continue to behave as expected.
  
  (4) Migrate alternative break-to-debugger state machine logic out of
      individual device drivers into centralised KDB code.  This has a
      number of upsides, but also one downside: it's now tricky to release
      sio spin locks when entering the debugger, so we don't.  However,
      similar logic does not exist in other device drivers, including uart.
  
  (5) dcons requires some special handling; unlike other console types, it
      allows overriding KDB's own debugger selection, so we need a new
      interface to KDB to allow that to work.
  
  GENERIC kernels in -CURRENT will now support break-to-debugger as long as
  appropriate boot/run-time options are set, which should improve the
  debuggability of BETA kernels significantly.
  
  MFC after:    3 weeks
  Reviewed by:  kib, nwhitehorn
  Approved by:  re (bz)

Modified:
  head/sys/dev/cfe/cfe_console.c
  head/sys/dev/dcons/dcons_os.c
  head/sys/dev/ofw/ofw_console.c
  head/sys/dev/sio/sio.c
  head/sys/dev/syscons/syscons.c
  head/sys/dev/uart/uart_core.c
  head/sys/kern/subr_kdb.c
  head/sys/pc98/cbus/sio.c
  head/sys/powerpc/mambo/mambo_console.c
  head/sys/sys/kdb.h

Modified: head/sys/dev/cfe/cfe_console.c
==============================================================================
--- head/sys/dev/cfe/cfe_console.c      Fri Aug 26 21:27:21 2011        
(r225202)
+++ head/sys/dev/cfe/cfe_console.c      Fri Aug 26 21:46:36 2011        
(r225203)
@@ -67,7 +67,7 @@ static int                    polltime;
 static struct callout_handle   cfe_timeouthandle
     = CALLOUT_HANDLE_INITIALIZER(&cfe_timeouthandle);
 
-#if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER)
+#if defined(KDB)
 static int                     alt_break_state;
 #endif
 
@@ -191,24 +191,8 @@ cfe_cngetc(struct consdev *cp)
        unsigned char ch;
 
        if (cfe_read(conhandle, &ch, 1) == 1) {
-#if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER)
-               int kdb_brk;
-
-               if ((kdb_brk = kdb_alt_break(ch, &alt_break_state)) != 0) {
-                       switch (kdb_brk) {
-                       case KDB_REQ_DEBUGGER:
-                               kdb_enter(KDB_WHY_BREAK,
-                                   "Break sequence on console");
-                               break;
-                       case KDB_REQ_PANIC:
-                               kdb_panic("Panic sequence on console");
-                               break;
-                       case KDB_REQ_REBOOT:
-                               kdb_reboot();
-                               break;
-
-                       }
-               }
+#if defined(KDB)
+               kdb_alt_break(ch, &alt_break_state);
 #endif
                return (ch);
        }

Modified: head/sys/dev/dcons/dcons_os.c
==============================================================================
--- head/sys/dev/dcons/dcons_os.c       Fri Aug 26 21:27:21 2011        
(r225202)
+++ head/sys/dev/dcons/dcons_os.c       Fri Aug 26 21:46:36 2011        
(r225203)
@@ -133,38 +133,21 @@ static struct ttydevsw dcons_ttydevsw = 
        .tsw_outwakeup  = dcons_outwakeup,
 };
 
-#if (defined(GDB) || defined(DDB)) && defined(ALT_BREAK_TO_DEBUGGER)
+#if (defined(GDB) || defined(DDB))
 static int
 dcons_check_break(struct dcons_softc *dc, int c)
 {
-       int kdb_brk;
 
        if (c < 0)
                return (c);
 
-       if ((kdb_brk = kdb_alt_break(c, &dc->brk_state)) != 0) {
-               switch (kdb_brk) {
-               case KDB_REQ_DEBUGGER:
-                       if ((dc->flags & DC_GDB) != 0) {
 #ifdef GDB
-                               if (gdb_cur == &dcons_gdb_dbgport) {
-                                       kdb_dbbe_select("gdb");
-                                       kdb_enter(KDB_WHY_BREAK,
-                                           "Break sequence on dcons gdb port");
-                               }
+       if ((dc->flags & DC_GDB) != 0 && gdb_cur == &dcons_gdb_dbgport)
+               kdb_alt_break_gdb(c, &dc->brk_state);
+       else
 #endif
-                       } else
-                               kdb_enter(KDB_WHY_BREAK,
-                                   "Break sequence on dcons console port");
-                       break;
-               case KDB_REQ_PANIC:
-                       kdb_panic("Panic sequence on dcons console port");
-                       break;
-               case KDB_REQ_REBOOT:
-                       kdb_reboot();
-                       break;
-               }
-       }
+               kdb_alt_break(c, &dc->brk_state);
+
        return (c);
 }
 #else

Modified: head/sys/dev/ofw/ofw_console.c
==============================================================================
--- head/sys/dev/ofw/ofw_console.c      Fri Aug 26 21:27:21 2011        
(r225202)
+++ head/sys/dev/ofw/ofw_console.c      Fri Aug 26 21:46:36 2011        
(r225203)
@@ -64,7 +64,7 @@ static int                    polltime;
 static struct callout_handle   ofw_timeouthandle
     = CALLOUT_HANDLE_INITIALIZER(&ofw_timeouthandle);
 
-#if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER)
+#if defined(KDB)
 static int                     alt_break_state;
 #endif
 
@@ -199,24 +199,8 @@ ofw_cngetc(struct consdev *cp)
        unsigned char ch;
 
        if (OF_read(stdin, &ch, 1) > 0) {
-#if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER)
-               int kdb_brk;
-
-               if ((kdb_brk = kdb_alt_break(ch, &alt_break_state)) != 0) {
-                       switch (kdb_brk) {
-                       case KDB_REQ_DEBUGGER:
-                               kdb_enter(KDB_WHY_BREAK,
-                                   "Break sequence on console");
-                               break;
-                       case KDB_REQ_PANIC:
-                               kdb_panic("Panic sequence on console");
-                               break;
-                       case KDB_REQ_REBOOT:
-                               kdb_reboot();
-                               break;
-
-                       }
-               }
+#if defined(KDB)
+               kdb_alt_break(ch, &alt_break_state);
 #endif
                return (ch);
        }

Modified: head/sys/dev/sio/sio.c
==============================================================================
--- head/sys/dev/sio/sio.c      Fri Aug 26 21:27:21 2011        (r225202)
+++ head/sys/dev/sio/sio.c      Fri Aug 26 21:46:36 2011        (r225203)
@@ -228,7 +228,7 @@ struct com_s {
 
        struct  pps_state pps;
        int     pps_bit;
-#ifdef ALT_BREAK_TO_DEBUGGER
+#ifdef KDB
        int     alt_brk_state;
 #endif
 
@@ -1102,8 +1102,7 @@ determined_type: ;
                }
                if (ret)
                        device_printf(dev, "could not activate interrupt\n");
-#if defined(KDB) && (defined(BREAK_TO_DEBUGGER) || \
-    defined(ALT_BREAK_TO_DEBUGGER))
+#if defined(KDB)
                /*
                 * Enable interrupts for early break-to-debugger support
                 * on the console.
@@ -1196,8 +1195,7 @@ comclose(tp)
        com->poll_output = FALSE;
        sio_setreg(com, com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
 
-#if defined(KDB) && (defined(BREAK_TO_DEBUGGER) || \
-    defined(ALT_BREAK_TO_DEBUGGER))
+#if defined(KDB)
        /*
         * Leave interrupts enabled and don't clear DTR if this is the
         * console. This allows us to detect break-to-debugger events
@@ -1483,9 +1481,8 @@ siointr1(com)
        u_char  modem_status;
        u_char  *ioptr;
        u_char  recv_data;
-#if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER)
-       int     kdb_brk;
 
+#ifdef KDB
 again:
 #endif
 
@@ -1518,27 +1515,9 @@ again:
                        else
                                recv_data = inb(com->data_port);
 #ifdef KDB
-#ifdef ALT_BREAK_TO_DEBUGGER
                        if (com->unit == comconsole &&
-                           (kdb_brk = kdb_alt_break(recv_data,
-                                       &com->alt_brk_state)) != 0) {
-                               mtx_unlock_spin(&sio_lock);
-                               switch (kdb_brk) {
-                               case KDB_REQ_DEBUGGER:
-                                       kdb_enter(KDB_WHY_BREAK,
-                                           "Break sequence on console");
-                                       break;
-                               case KDB_REQ_PANIC:
-                                       kdb_panic("panic on console");
-                                       break;
-                               case KDB_REQ_REBOOT:
-                                       kdb_reboot();
-                                       break;
-                               }
-                               mtx_lock_spin(&sio_lock);
+                           kdb_alt_break(recv_data, &com->alt_brk_state) != 0)
                                goto again;
-                       }
-#endif /* ALT_BREAK_TO_DEBUGGER */
 #endif /* KDB */
                        if (line_status & (LSR_BI | LSR_FE | LSR_PE)) {
                                /*
@@ -1554,10 +1533,9 @@ again:
                                 * Note: BI together with FE/PE means just BI.
                                 */
                                if (line_status & LSR_BI) {
-#if defined(KDB) && defined(BREAK_TO_DEBUGGER)
+#if defined(KDB)
                                        if (com->unit == comconsole) {
-                                               kdb_enter(KDB_WHY_BREAK,
-                                                   "Line break on console");
+                                               kdb_break();
                                                goto cont;
                                        }
 #endif

Modified: head/sys/dev/syscons/syscons.c
==============================================================================
--- head/sys/dev/syscons/syscons.c      Fri Aug 26 21:27:21 2011        
(r225202)
+++ head/sys/dev/syscons/syscons.c      Fri Aug 26 21:46:36 2011        
(r225203)
@@ -3514,7 +3514,7 @@ next_code:
            case DBG:
 #ifndef SC_DISABLE_KDBKEY
                if (enable_kdbkey)
-                       kdb_enter(KDB_WHY_BREAK, "manual escape to debugger");
+                       kdb_break();
 #endif
                break;
 

Modified: head/sys/dev/uart/uart_core.c
==============================================================================
--- head/sys/dev/uart/uart_core.c       Fri Aug 26 21:27:21 2011        
(r225202)
+++ head/sys/dev/uart/uart_core.c       Fri Aug 26 21:46:36 2011        
(r225203)
@@ -118,10 +118,10 @@ uart_intr_break(void *arg)
 {
        struct uart_softc *sc = arg;
 
-#if defined(KDB) && defined(BREAK_TO_DEBUGGER)
+#if defined(KDB)
        if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
-               kdb_enter(KDB_WHY_BREAK, "Line break on console");
-               return (0);
+               if (kdb_break())
+                       return (0);
        }
 #endif
        if (sc->sc_opened)
@@ -170,26 +170,10 @@ uart_intr_rxready(void *arg)
 
        rxp = sc->sc_rxput;
        UART_RECEIVE(sc);
-#if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER)
+#if defined(KDB)
        if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
                while (rxp != sc->sc_rxput) {
-                       int kdb_brk;
-
-                       if ((kdb_brk = kdb_alt_break(sc->sc_rxbuf[rxp++],
-                           &sc->sc_altbrk)) != 0) {
-                               switch (kdb_brk) {
-                               case KDB_REQ_DEBUGGER:
-                                       kdb_enter(KDB_WHY_BREAK,
-                                           "Break sequence on console");
-                                       break;
-                               case KDB_REQ_PANIC:
-                                       kdb_panic("Panic sequence on console");
-                                       break;
-                               case KDB_REQ_REBOOT:
-                                       kdb_reboot();
-                                       break;
-                               }
-                       }
+                       kdb_alt_break(sc->sc_rxbuf[rxp++], &sc->sc_altbrk);
                        if (rxp == sc->sc_rxbufsz)
                                rxp = 0;
                }

Modified: head/sys/kern/subr_kdb.c
==============================================================================
--- head/sys/kern/subr_kdb.c    Fri Aug 26 21:27:21 2011        (r225202)
+++ head/sys/kern/subr_kdb.c    Fri Aug 26 21:46:36 2011        (r225203)
@@ -57,6 +57,21 @@ struct pcb *kdb_thrctx = NULL;
 struct thread *kdb_thread = NULL;
 struct trapframe *kdb_frame = NULL;
 
+#ifdef BREAK_TO_DEBUGGER
+#define        KDB_BREAK_TO_DEBUGGER   1
+#else
+#define        KDB_BREAK_TO_DEBUGGER   0
+#endif
+
+#ifdef ALT_BREAK_TO_DEBUGGER
+#define        KDB_ALT_BREAK_TO_DEBUGGER       1
+#else
+#define        KDB_ALT_BREAK_TO_DEBUGGER       0
+#endif
+
+static int     kdb_break_to_debugger = KDB_BREAK_TO_DEBUGGER;
+static int     kdb_alt_break_to_debugger = KDB_ALT_BREAK_TO_DEBUGGER;
+
 KDB_BACKEND(null, NULL, NULL, NULL);
 SET_DECLARE(kdb_dbbe_set, struct kdb_dbbe);
 
@@ -87,6 +102,15 @@ SYSCTL_PROC(_debug_kdb, OID_AUTO, trap, 
 SYSCTL_PROC(_debug_kdb, OID_AUTO, trap_code, CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
     kdb_sysctl_trap_code, "I", "set to cause a page fault via code access");
 
+SYSCTL_INT(_debug_kdb, OID_AUTO, break_to_debugger, CTLTYPE_INT | CTLFLAG_RW |
+    CTLFLAG_TUN, &kdb_break_to_debugger, 0, "Enable break to debugger");
+TUNABLE_INT("debug.kdb.break_to_debugger", &kdb_break_to_debugger);
+
+SYSCTL_INT(_debug_kdb, OID_AUTO, alt_break_to_debugger, CTLTYPE_INT |
+    CTLFLAG_RW | CTLFLAG_TUN, &kdb_alt_break_to_debugger, 0,
+    "Enable alternative break to debugger");
+TUNABLE_INT("debug.kdb.alt_break_to_debugger", &kdb_alt_break_to_debugger);
+
 /*
  * Flag to indicate to debuggers why the debugger was entered.
  */
@@ -241,7 +265,17 @@ enum {
 };
 
 int
-kdb_alt_break(int key, int *state)
+kdb_break(void)
+{
+
+       if (!kdb_break_to_debugger)
+               return (0);
+       kdb_enter(KDB_WHY_BREAK, "Break to debugger");
+       return (KDB_REQ_DEBUGGER);
+}
+
+static int
+kdb_alt_break_state(int key, int *state)
 {
        int brk;
 
@@ -275,6 +309,53 @@ kdb_alt_break(int key, int *state)
        return (brk);
 }
 
+static int
+kdb_alt_break_internal(int key, int *state, int force_gdb)
+{
+       int brk;
+
+       if (!kdb_alt_break_to_debugger)
+               return (0);
+       brk = kdb_alt_break_state(key, state);
+       switch (brk) {
+       case KDB_REQ_DEBUGGER:
+               if (force_gdb)
+                       kdb_dbbe_select("gdb");
+               kdb_enter(KDB_WHY_BREAK, "Break to debugger");
+               break;
+
+       case KDB_REQ_PANIC:
+               if (force_gdb)
+                       kdb_dbbe_select("gdb");
+               kdb_panic("Panic sequence on console");
+               break;
+
+       case KDB_REQ_REBOOT:
+               kdb_reboot();
+               break;
+       }
+       return (0);
+}
+
+int
+kdb_alt_break(int key, int *state)
+{
+
+       return (kdb_alt_break_internal(key, state, 0));
+}
+
+/*
+ * This variation on kdb_alt_break() is used only by dcons, which has its own
+ * configuration flag to force GDB use regardless of the global KDB
+ * configuration.
+ */
+int
+kdb_alt_break_gdb(int key, int *state)
+{
+
+       return (kdb_alt_break_internal(key, state, 1));
+}
+
 /*
  * Print a backtrace of the calling thread. The backtrace is generated by
  * the selected debugger, provided it supports backtraces. If no debugger

Modified: head/sys/pc98/cbus/sio.c
==============================================================================
--- head/sys/pc98/cbus/sio.c    Fri Aug 26 21:27:21 2011        (r225202)
+++ head/sys/pc98/cbus/sio.c    Fri Aug 26 21:46:36 2011        (r225203)
@@ -310,7 +310,7 @@ struct com_s {
 
        struct  pps_state pps;
        int     pps_bit;
-#ifdef ALT_BREAK_TO_DEBUGGER
+#ifdef KDB
        int     alt_brk_state;
 #endif
 
@@ -1752,8 +1752,7 @@ determined_type: ;
                }
                if (ret)
                        device_printf(dev, "could not activate interrupt\n");
-#if defined(KDB) && (defined(BREAK_TO_DEBUGGER) || \
-    defined(ALT_BREAK_TO_DEBUGGER))
+#if defined(KDB)
                /*
                 * Enable interrupts for early break-to-debugger support
                 * on the console.
@@ -1896,8 +1895,7 @@ comclose(tp)
        sio_setreg(com, com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
 #endif
 
-#if defined(KDB) && (defined(BREAK_TO_DEBUGGER) || \
-    defined(ALT_BREAK_TO_DEBUGGER))
+#if defined(KDB)
        /*
         * Leave interrupts enabled and don't clear DTR if this is the
         * console. This allows us to detect break-to-debugger events
@@ -2272,7 +2270,7 @@ siointr1(com)
        u_char  rsa_buf_status = 0;
        int     rsa_tx_fifo_size = 0;
 #endif /* PC98 */
-#if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER)
+#if defined(KDB)
        int     kdb_brk;
 
 again:
@@ -2369,27 +2367,11 @@ more_intr:
                        else
                                recv_data = inb(com->data_port);
 #ifdef KDB
-#ifdef ALT_BREAK_TO_DEBUGGER
                        if (com->unit == comconsole &&
                            (kdb_brk = kdb_alt_break(recv_data,
                                        &com->alt_brk_state)) != 0) {
-                               mtx_unlock_spin(&sio_lock);
-                               switch (kdb_brk) {
-                               case KDB_REQ_DEBUGGER:
-                                       kdb_enter(KDB_WHY_BREAK,
-                                           "Break sequence on console");
-                                       break;
-                               case KDB_REQ_PANIC:
-                                       kdb_panic("panic on console");
-                                       break;
-                               case KDB_REQ_REBOOT:
-                                       kdb_reboot();
-                                       break;
-                               }
-                               mtx_lock_spin(&sio_lock);
                                goto again;
                        }
-#endif /* ALT_BREAK_TO_DEBUGGER */
 #endif /* KDB */
                        if (line_status & (LSR_BI | LSR_FE | LSR_PE)) {
                                /*
@@ -2405,7 +2387,7 @@ more_intr:
                                 * Note: BI together with FE/PE means just BI.
                                 */
                                if (line_status & LSR_BI) {
-#if defined(KDB) && defined(BREAK_TO_DEBUGGER)
+#if defined(KDB)
                                        if (com->unit == comconsole) {
                                                kdb_enter(KDB_WHY_BREAK,
                                                    "Line break on console");

Modified: head/sys/powerpc/mambo/mambo_console.c
==============================================================================
--- head/sys/powerpc/mambo/mambo_console.c      Fri Aug 26 21:27:21 2011        
(r225202)
+++ head/sys/powerpc/mambo/mambo_console.c      Fri Aug 26 21:46:36 2011        
(r225203)
@@ -60,7 +60,7 @@ static int                    polltime;
 static struct callout          mambo_callout;
 static struct tty              *tp = NULL;
 
-#if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER)
+#if defined(KDB)
 static int                     alt_break_state;
 #endif
 
@@ -156,24 +156,8 @@ mambo_cngetc(struct consdev *cp)
        ch = mambocall(MAMBO_CONSOLE_READ);
 
        if (ch > 0 && ch < 0xff) {
-#if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER)
-               int kdb_brk;
-
-               if ((kdb_brk = kdb_alt_break(ch, &alt_break_state)) != 0) {
-                       switch (kdb_brk) {
-                       case KDB_REQ_DEBUGGER:
-                               kdb_enter(KDB_WHY_BREAK,
-                                   "Break sequence on console");
-                               break;
-                       case KDB_REQ_PANIC:
-                               kdb_panic("Panic sequence on console");
-                               break;
-                       case KDB_REQ_REBOOT:
-                               kdb_reboot();
-                               break;
-
-                       }
-               }
+#if defined(KDB)
+               kdb_alt_break(ch, &alt_break_state);
 #endif
                return (ch);
        }

Modified: head/sys/sys/kdb.h
==============================================================================
--- head/sys/sys/kdb.h  Fri Aug 26 21:27:21 2011        (r225202)
+++ head/sys/sys/kdb.h  Fri Aug 26 21:46:36 2011        (r225203)
@@ -64,6 +64,8 @@ extern struct pcb *kdb_thrctx;                /* Curre
 extern struct thread *kdb_thread;      /* Current thread. */
 
 int    kdb_alt_break(int, int *);
+int    kdb_alt_break_gdb(int, int *);
+int    kdb_break(void);
 void   kdb_backtrace(void);
 int    kdb_dbbe_select(const char *);
 void   kdb_enter(const char *, const char *);
_______________________________________________
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