Date: Fri, 18 Feb 2011 22:25:11 +0000 (UTC) From: Matthew D Fleming <mdf@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r218825 - in head/sys: ddb gdb kern Message-ID: <201102182225.p1IMPBP6074753@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mdf Date: Fri Feb 18 22:25:11 2011 New Revision: 218825 URL: http://svn.freebsd.org/changeset/base/218825 Log: 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. MFC after: 1 month Modified: head/sys/ddb/db_command.c head/sys/gdb/gdb_main.c head/sys/gdb/gdb_packet.c head/sys/kern/subr_kdb.c Modified: head/sys/ddb/db_command.c ============================================================================== --- head/sys/ddb/db_command.c Fri Feb 18 21:44:53 2011 (r218824) +++ head/sys/ddb/db_command.c Fri Feb 18 22:25:11 2011 (r218825) @@ -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: head/sys/gdb/gdb_main.c ============================================================================== --- head/sys/gdb/gdb_main.c Fri Feb 18 21:44:53 2011 (r218824) +++ head/sys/gdb/gdb_main.c Fri Feb 18 22:25:11 2011 (r218825) @@ -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: head/sys/gdb/gdb_packet.c ============================================================================== --- head/sys/gdb/gdb_packet.c Fri Feb 18 21:44:53 2011 (r218824) +++ head/sys/gdb/gdb_packet.c Fri Feb 18 22:25:11 2011 (r218825) @@ -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: head/sys/kern/subr_kdb.c ============================================================================== --- head/sys/kern/subr_kdb.c Fri Feb 18 21:44:53 2011 (r218824) +++ head/sys/kern/subr_kdb.c Fri Feb 18 22:25:11 2011 (r218825) @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include <sys/malloc.h> #include <sys/pcpu.h> #include <sys/proc.h> +#include <sys/sbuf.h> #include <sys/smp.h> #include <sys/stack.h> #include <sys/sysctl.h> @@ -108,33 +109,17 @@ const char * volatile kdb_why = KDB_WHY_ static int kdb_sysctl_available(SYSCTL_HANDLER_ARGS) { - struct kdb_dbbe *be, **iter; - char *avail, *p; - ssize_t len, sz; + struct kdb_dbbe **iter; + struct sbuf sbuf; int error; - sz = 0; + sbuf_new_for_sysctl(&sbuf, NULL, 64, req); SET_FOREACH(iter, kdb_dbbe_set) { - be = *iter; - if (be->dbbe_active == 0) - sz += strlen(be->dbbe_name) + 1; + if ((*iter)->dbbe_active == 0) + sbuf_printf(&sbuf, "%s ", (*iter)->dbbe_name); } - sz++; - avail = malloc(sz, M_TEMP, M_WAITOK); - p = avail; - *p = '\0'; - - SET_FOREACH(iter, kdb_dbbe_set) { - be = *iter; - if (be->dbbe_active == 0) { - len = snprintf(p, sz, "%s ", be->dbbe_name); - p += len; - sz -= len; - } - } - KASSERT(sz >= 0, ("%s", __func__)); - error = sysctl_handle_string(oidp, avail, 0, req); - free(avail, M_TEMP); + error = sbuf_finish(&sbuf); + sbuf_delete(&sbuf); return (error); } @@ -144,10 +129,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 +497,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 +529,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--;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201102182225.p1IMPBP6074753>