--- amd64/amd64/machdep.c	2007/12/12 20:26:36
+++ amd64/amd64/machdep.c	2007/12/18 10:02:18
@@ -1277,7 +1277,8 @@
 
 #ifdef KDB
 	if (boothowto & RB_KDB)
-		kdb_enter("Boot flags requested debugger");
+		kdb_enter(KDB_WHY_BOOTFLAGS,
+		    "Boot flags requested debugger");
 #endif
 
 	identify_cpu();		/* Final stage of CPU initialization */
--- amd64/amd64/mp_watchdog.c	2007/06/05 00:03:37
+++ amd64/amd64/mp_watchdog.c	2007/12/14 14:01:55
@@ -203,7 +203,7 @@
 			if (watchdog_nmi)
 				watchdog_ipi_nmi();
 			else
-				kdb_enter("mp_watchdog");
+				kdb_enter(KDB_WHY_WATCHDOG, "mp_watchdog");
 		}
 	}
 	bcopy(old_pcomm, p->p_comm, MAXCOMLEN + 1);
--- arm/at91/uart_dev_at91usart.c	2007/04/02 22:02:04
+++ arm/at91/uart_dev_at91usart.c	2007/12/14 14:01:55
@@ -508,7 +508,7 @@
 #if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER)
 	if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
 		if (kdb_alt_break(key, &sc->sc_altbrk))
-			kdb_enter("Break sequence to console");
+			kdb_enter(KDB_WHY_BREAK, "Break sequence to console");
 	}
 #endif
 	uart_rx_put(sc, key);	
--- cam/scsi/scsi_low.h	2005/01/05 22:36:13
+++ cam/scsi/scsi_low.h	2007/12/14 14:01:55
@@ -87,7 +87,7 @@
 
 #ifdef	__FreeBSD__
 #undef	MSG_IDENTIFY
-#define	SCSI_LOW_DEBUGGER(dev)	kdb_enter(dev)
+#define	SCSI_LOW_DEBUGGER(dev)	kdb_enter(KDB_WHY_CAM, dev)
 #define	SCSI_LOW_DELAY(mu)	DELAY((mu))
 #define	SCSI_LOW_SPLSCSI	splcam
 #define	SCSI_LOW_BZERO(pt, size)	bzero((pt), (size))
--- compat/ndis/subr_ntoskrnl.c	2007/12/03 23:45:51
+++ compat/ndis/subr_ntoskrnl.c	2007/12/14 14:01:55
@@ -3632,7 +3632,7 @@
 #if __FreeBSD_version < 502113
 	Debugger("DbgBreakPoint(): breakpoint");
 #else
-	kdb_enter("DbgBreakPoint(): breakpoint");
+	kdb_enter(KDB_WHY_NDIS, "DbgBreakPoint(): breakpoint");
 #endif
 }
 
--- dev/acpica/Osd/OsdDebug.c	2007/03/22 18:23:04
+++ dev/acpica/Osd/OsdDebug.c	2007/12/14 14:01:55
@@ -73,13 +73,13 @@
 	printf("ACPI fatal signal, type 0x%x code 0x%x argument 0x%x",
 	      fatal->Type, fatal->Code, fatal->Argument);
 #ifdef ACPI_DEBUG
-	kdb_enter("AcpiOsSignal");
+	kdb_enter(KDB_WHY_ACPI, "AcpiOsSignal");
 #endif
 	break;
 
     case ACPI_SIGNAL_BREAKPOINT:
 #ifdef ACPI_DEBUG
-	kdb_enter((char *)Info);
+	kdb_enter(KDB_WHY_ACPI, (char *)Info);
 #endif
 	break;
 
--- dev/dcons/dcons_os.c	2007/08/17 05:36:58
+++ dev/dcons/dcons_os.c	2007/12/14 14:01:55
@@ -207,11 +207,13 @@
 #ifdef GDB
 			if (gdb_cur == &dcons_gdb_dbgport) {
 				kdb_dbbe_select("gdb");
-				kdb_enter("Break sequence on dcons gdb port");
+				kdb_enter(KDB_WHY_BREAK,
+				    "Break sequence on dcons gdb port");
 			}
 #endif
 		} else
-			kdb_enter("Break sequence on dcons console port");
+			kdb_enter(KDB_WHY_BREAK,
+			    "Break sequence on dcons console port");
 	}
 #else
 	switch (dc->brk_state) {
--- dev/ofw/ofw_console.c	2006/11/06 17:47:49
+++ dev/ofw/ofw_console.c	2007/12/14 14:01:55
@@ -282,7 +282,7 @@
 	if (OF_read(stdin, &ch, 1) > 0) {
 #if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER)
 		if (kdb_alt_break(ch, &alt_break_state))
-			kdb_enter("Break sequence on console");
+			kdb_enter(KDB_WHY_BREAK, "Break sequence on console");
 #endif
 		return (ch);
 	}
--- dev/sio/sio.c	2007/12/05 05:22:36
+++ dev/sio/sio.c	2007/12/14 16:36:43
@@ -1502,7 +1502,8 @@
 #ifdef ALT_BREAK_TO_DEBUGGER
 			if (com->unit == comconsole &&
 			    kdb_alt_break(recv_data, &com->alt_brk_state) != 0)
-				kdb_enter("Break sequence on console");
+				kdb_enter(KDB_WHY_BREAK,
+				    "Break sequence on console");
 #endif /* ALT_BREAK_TO_DEBUGGER */
 #endif /* KDB */
 			if (line_status & (LSR_BI | LSR_FE | LSR_PE)) {
@@ -1521,7 +1522,8 @@
 				if (line_status & LSR_BI) {
 #if defined(KDB) && defined(BREAK_TO_DEBUGGER)
 					if (com->unit == comconsole) {
-						kdb_enter("Line break on console");
+						kdb_enter(KDB_WHY_BREAK,
+						    "Line break on console");
 						goto cont;
 					}
 #endif
--- dev/syscons/syscons.c	2007/09/20 04:07:12
+++ dev/syscons/syscons.c	2007/12/14 14:01:55
@@ -3373,7 +3373,7 @@
 	    case DBG:
 #ifndef SC_DISABLE_KDBKEY
 		if (enable_kdbkey)
-			kdb_enter("manual escape to debugger");
+			kdb_enter(KDB_WHY_BREAK, "manual escape to debugger");
 #endif
 		break;
 
--- dev/uart/uart_core.c	2007/04/02 22:02:04
+++ dev/uart/uart_core.c	2007/12/14 14:01:55
@@ -122,7 +122,7 @@
 
 #if defined(KDB) && defined(BREAK_TO_DEBUGGER)
 	if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
-		kdb_enter("Line break on console");
+		kdb_enter(KDB_WHY_BREAK, "Line break on console");
 		return (0);
 	}
 #endif
@@ -176,7 +176,8 @@
 	if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
 		while (rxp != sc->sc_rxput) {
 			if (kdb_alt_break(sc->sc_rxbuf[rxp++], &sc->sc_altbrk))
-				kdb_enter("Break sequence on console");
+				kdb_enter(KDB_WHY_BREAK,
+				    "Break sequence on console");
 			if (rxp == sc->sc_rxbufsz)
 				rxp = 0;
 		}
--- fs/unionfs/union_subr.c	2007/10/24 19:06:35
+++ fs/unionfs/union_subr.c	2007/12/14 14:01:55
@@ -1062,7 +1062,8 @@
 	if (vp->v_op != unionfs_vnodeop_p) {
 		printf("unionfs_checkuppervp: on non-unionfs-node.\n");
 #ifdef KDB
-		kdb_enter("unionfs_checkuppervp: on non-unionfs-node.\n");
+		kdb_enter(KDB_WHY_UNIONFS,
+		    "unionfs_checkuppervp: on non-unionfs-node.\n");
 #endif
 		panic("unionfs_checkuppervp");
 	};
@@ -1081,7 +1082,8 @@
 	if (vp->v_op != unionfs_vnodeop_p) {
 		printf("unionfs_checklowervp: on non-unionfs-node.\n");
 #ifdef KDB
-		kdb_enter("unionfs_checklowervp: on non-unionfs-node.\n");
+		kdb_enter(KDB_WHY_UNIONFS,
+		    "unionfs_checklowervp: on non-unionfs-node.\n");
 #endif
 		panic("unionfs_checklowervp");
 	};
--- i386/i386/machdep.c	2007/12/16 20:42:27
+++ i386/i386/machdep.c	2007/12/17 14:22:06
@@ -2275,7 +2275,7 @@
 
 #ifdef KDB
 	if (boothowto & RB_KDB)
-		kdb_enter("Boot flags requested debugger");
+		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
 #endif
 
 	finishidentcpu();	/* Final stage of CPU initialization */
--- i386/i386/mp_watchdog.c	2007/06/05 00:03:37
+++ i386/i386/mp_watchdog.c	2007/12/14 14:01:55
@@ -203,7 +203,7 @@
 			if (watchdog_nmi)
 				watchdog_ipi_nmi();
 			else
-				kdb_enter("mp_watchdog");
+				kdb_enter(KDB_WHY_WATCHDOG, "mp_watchdog");
 		}
 	}
 	bcopy(old_pcomm, p->p_comm, MAXCOMLEN + 1);
--- ia64/ia64/machdep.c	2007/11/14 20:26:24
+++ ia64/ia64/machdep.c	2007/12/14 14:01:55
@@ -824,7 +824,8 @@
 
 #ifdef KDB
 	if (boothowto & RB_KDB)
-		kdb_enter("Boot flags requested debugger\n");
+		kdb_enter(KDB_WHY_BOOTFLAGS,
+		    "Boot flags requested debugger\n");
 #endif
 
 	ia64_set_tpr(0);
--- kern/kern_clock.c	2007/11/29 08:42:24
+++ kern/kern_clock.c	2007/12/14 14:01:55
@@ -637,7 +637,7 @@
 
 #if defined(KDB) && !defined(KDB_UNATTENDED)
 	kdb_backtrace();
-	kdb_enter("watchdog timeout");
+	kdb_enter(KDB_WHY_WATCHDOG, "watchdog timeout");
 #else
 	panic("watchdog timeout");
 #endif
--- kern/kern_shutdown.c	2007/10/26 08:01:41
+++ kern/kern_shutdown.c	2007/12/14 14:01:55
@@ -544,7 +552,7 @@
 	if (newpanic && trace_on_panic)
 		kdb_backtrace();
 	if (debugger_on_panic)
-		kdb_enter("panic");
+		kdb_enter(KDB_WHY_PANIC, "panic");
 #ifdef RESTARTABLE_PANICS
 	/* See if the user aborted the panic, in which case we continue. */
 	if (panicstr == NULL) {
--- kern/subr_kdb.c	2007/09/17 05:32:36
+++ kern/subr_kdb.c	2007/12/15 00:21:55
@@ -97,6 +97,11 @@
 TUNABLE_INT("debug.kdb.stop_cpus", &kdb_stop_cpus);
 #endif
 
+/*
+ * Flag to indicate to debuggers why the debugger was entered.
+ */
+const char * volatile kdb_why = KDB_WHY_UNSET;
+
 static int
 kdb_sysctl_available(SYSCTL_HANDLER_ARGS)
 {
@@ -163,7 +168,7 @@
 		return (error);
 	if (kdb_active)
 		return (EBUSY);
-	kdb_enter("sysctl debug.kdb.enter");
+	kdb_enter(KDB_WHY_SYSCTL, "sysctl debug.kdb.enter");
 	return (0);
 }
 
@@ -295,17 +300,20 @@
  * Enter the currently selected debugger. If a message has been provided,
  * it is printed first. If the debugger does not support the enter method,
  * it is entered by using breakpoint(), which enters the debugger through
- * kdb_trap().
+ * kdb_trap().  The 'why' argument will contain a more mechanically usable
+ * string than 'msg', and is relied upon by DDB scripting to identify the
+ * reason for entering the debugger so that the right script can be run.
  */
-
 void
-kdb_enter(const char *msg)
+kdb_enter(const char *why, const char *msg)
 {
 
 	if (kdb_dbbe != NULL && kdb_active == 0) {
 		if (msg != NULL)
 			printf("KDB: enter: %s\n", msg);
+		kdb_why = why;
 		breakpoint();
+		kdb_why = KDB_WHY_UNSET;
 	}
 }
 
--- kern/subr_witness.c	2007/11/24 04:37:19
+++ kern/subr_witness.c	2007/12/14 14:01:55
@@ -1123,7 +1123,7 @@
 	if (witness_trace)
 		kdb_backtrace();
 	if (witness_kdb)
-		kdb_enter(__func__);
+		kdb_enter(KDB_WHY_WITNESS, __func__);
 #endif
 }
 
@@ -1396,7 +1396,7 @@
 		panic("witness_warn");
 #ifdef KDB
 	else if (witness_kdb && n)
-		kdb_enter(__func__);
+		kdb_enter(KDB_WHY_WITNESS, __func__);
 	else if (witness_trace && n)
 		kdb_backtrace();
 #endif
--- kern/vfs_subr.c	2007/12/05 09:35:47
+++ kern/vfs_subr.c	2007/12/14 14:01:55
@@ -3456,7 +3456,7 @@
 	if (vfs_badlock_print)
 		printf("%s: %p %s\n", str, (void *)vp, msg);
 	if (vfs_badlock_ddb)
-		kdb_enter("lock violation");
+		kdb_enter(KDB_WHY_VFSLOCK, "lock violation");
 }
 
 void
@@ -3576,7 +3576,7 @@
 			printf(
 			    "VOP_STRATEGY: bp is not locked but should be\n");
 		if (vfs_badlock_ddb)
-			kdb_enter("lock violation");
+			kdb_enter(KDB_WHY_VFSLOCK, "lock violation");
 	}
 #endif
 }
--- netgraph/ng_base.c	2007/11/14 11:26:53
+++ netgraph/ng_base.c	2007/12/14 14:01:55
@@ -3465,12 +3465,12 @@
 	do {								\
 		if (NGI_NODE(item) ) {					\
 			printf("item already has node");		\
-			kdb_enter("has node");				\
+			kdb_enter(KDB_WHY_NETGRAPH, "has node");	\
 			NGI_CLR_NODE(item);				\
 		}							\
 		if (NGI_HOOK(item) ) {					\
 			printf("item already has hook");		\
-			kdb_enter("has hook");				\
+			kdb_enter(KDB_WHY_NETGRAPH, "has hook");	\
 			NGI_CLR_HOOK(item);				\
 		}							\
 	} while (0)
--- pc98/cbus/sio.c	2007/10/12 06:06:37
+++ pc98/cbus/sio.c	2007/12/14 14:01:55
@@ -2369,7 +2369,8 @@
 #ifdef ALT_BREAK_TO_DEBUGGER
 			if (com->unit == comconsole &&
 			    kdb_alt_break(recv_data, &com->alt_brk_state) != 0)
-				kdb_enter("Break sequence on console");
+				kdb_enter(KDB_WHY_BREAK,
+				    "Break sequence on console");
 #endif /* ALT_BREAK_TO_DEBUGGER */
 #endif /* KDB */
 			if (line_status & (LSR_BI | LSR_FE | LSR_PE)) {
@@ -2388,7 +2389,8 @@
 				if (line_status & LSR_BI) {
 #if defined(KDB) && defined(BREAK_TO_DEBUGGER)
 					if (com->unit == comconsole) {
-						kdb_enter("Line break on console");
+						kdb_enter(KDB_WHY_BREAK,
+						    "Line break on console");
 						goto cont;
 					}
 #endif
--- pc98/pc98/machdep.c	2007/11/14 12:31:45
+++ pc98/pc98/machdep.c	2007/12/14 14:01:55
@@ -2061,7 +2061,7 @@
 
 #ifdef KDB
 	if (boothowto & RB_KDB)
-		kdb_enter("Boot flags requested debugger");
+		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
 #endif
 
 	finishidentcpu();	/* Final stage of CPU initialization */
--- powerpc/aim/machdep.c	2007/12/14 22:44:37
+++ powerpc/aim/machdep.c	2007/12/17 14:25:55
@@ -398,7 +398,8 @@
 
 #ifdef KDB
 	if (boothowto & RB_KDB)
-		kdb_enter("Boot flags requested debugger");
+		kdb_enter(KDB_WHY_BOOTFLAGS,
+		    "Boot flags requested debugger");
 #endif
 }
 
--- powerpc/powermac/pswitch.c	2007/03/02 15:17:21
+++ powerpc/powermac/pswitch.c	2007/12/14 14:01:55
@@ -139,6 +139,6 @@
 
 	dev = (device_t)arg;
 
-	kdb_enter(device_get_nameunit(dev));
+	kdb_enter(KDB_WHY_POWERPC, device_get_nameunit(dev));
 	return (FILTER_HANDLED);
 }
--- security/mac_test/mac_test.c	2007/10/30 00:06:24
+++ security/mac_test/mac_test.c	2007/12/14 14:01:55
@@ -117,7 +117,7 @@
 #define	COUNTER_INC(variable)	atomic_add_int(&counter_##variable, 1)
 
 #ifdef KDB
-#define	DEBUGGER(func, string)	kdb_enter((string))
+#define	DEBUGGER(func, string)	kdb_enter(KDB_WHY_MAC, (string))
 #else
 #define	DEBUGGER(func, string)	printf("mac_test: %s: %s\n", (func), (string))
 #endif
--- sparc64/pci/psycho.c	2007/12/01 19:46:02
+++ sparc64/pci/psycho.c	2007/12/14 14:01:55
@@ -850,7 +850,7 @@
 #ifdef DEBUGGER_ON_POWERFAIL
 	struct psycho_softc *sc = arg;
 
-	kdb_enter("powerfail");
+	kdb_enter(KDB_WHY_POWERFAIL, "powerfail");
 #else
 	static int shutdown;
 
--- sparc64/sparc64/machdep.c	2007/11/05 11:36:50
+++ sparc64/sparc64/machdep.c	2007/12/14 14:01:55
@@ -448,7 +448,7 @@
 
 #ifdef KDB
 	if (boothowto & RB_KDB)
-		kdb_enter("Boot flags requested debugger");
+		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
 #endif
 }
 
--- sparc64/sparc64/trap.c	2007/06/04 21:44:15
+++ sparc64/sparc64/trap.c	2007/12/14 14:01:55
@@ -289,7 +289,7 @@
 			}
 			if (debugger_on_signal &&
 			    (sig == 4 || sig == 10 || sig == 11))
-				kdb_enter("trapsig");
+				kdb_enter(KDB_WHY_TRAPSIG, "trapsig");
 			ksiginfo_init_trap(&ksi);
 			ksi.ksi_signo = sig;
 			ksi.ksi_code = (int)tf->tf_type; /* XXX not POSIX */
--- sun4v/sun4v/hvcons.c	2007/02/23 12:24:01
+++ sun4v/sun4v/hvcons.c	2007/12/14 14:01:55
@@ -224,10 +224,10 @@
 	while ((l = hv_cons_getchar(&ch)) != H_EOK) {
 #if defined(KDB)
 		if (l == H_BREAK || l ==  H_HUP)
-			kdb_enter("Break sequence on console");
+			kdb_enter(KDB_WHY_BREAK, "Break sequence on console");
 
 	if (kdb_alt_break(ch, &alt_break_state))
-		kdb_enter("Break sequence on console");
+		kdb_enter(KDB_WHY_BREAK, "Break sequence on console");
 #endif
 		if (l != -2 && l != 0) {
 			return (-1);
@@ -248,9 +248,9 @@
 	if ((l = hv_cons_getchar(&ch)) == H_EOK) {
 #if defined(KDB)
 		if (l == H_BREAK || l ==  H_HUP)
-			kdb_enter("Break sequence on console");
+			kdb_enter(KDB_WHY_BREAK, "Break sequence on console");
 		if (kdb_alt_break(ch, &alt_break_state))
-			kdb_enter("Break sequence on console");
+			kdb_enter(KDB_WHY_BREAK, "Break sequence on console");
 #endif
 		return (ch);
 	}
--- sun4v/sun4v/machdep.c	2007/11/05 11:36:50
+++ sun4v/sun4v/machdep.c	2007/12/14 14:01:55
@@ -510,7 +510,7 @@
 
 #ifdef KDB
 	if (boothowto & RB_KDB)
-		kdb_enter("Boot flags requested debugger");
+		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
 #endif
 	BVPRINTF("sparc64_init done\n");
 }
--- sun4v/sun4v/trap.c	2007/11/14 06:27:32
+++ sun4v/sun4v/trap.c	2007/12/14 14:01:55
@@ -366,7 +366,7 @@
 			}
 			if (debugger_on_signal &&
 			    (sig == 4 || sig == 10 || sig == 11))
-				kdb_enter("trapsig");
+				kdb_enter(KDB_WHY_TRAPSIG, "trapsig");
 #ifdef VERBOSE
 			if (sig == 4 || sig == 10 || sig == 11)
 				printf("trap: %ld:%s: 0x%lx at 0x%lx on cpu=%d sig=%d proc=%s\n", 
--- sys/kdb.h	2005/04/20 20:55:48
+++ sys/kdb.h	2007/12/15 02:20:56
@@ -66,7 +66,7 @@
 int	kdb_alt_break(int, int *);
 void	kdb_backtrace(void);
 int	kdb_dbbe_select(const char *);
-void	kdb_enter(const char *);
+void	kdb_enter(const char *, const char *);
 void	kdb_init(void);
 void *	kdb_jmpbuf(jmp_buf);
 void	kdb_reenter(void);
@@ -78,4 +78,31 @@
 int	kdb_thr_select(struct thread *);
 int	kdb_trap(int, int, struct trapframe *);
 
+/*
+ * KDB enters the debugger via breakpoint(), which leaves the debugger without
+ * a lot of information about why it was entered.  This simple enumerated set
+ * captures some basic information.
+ *
+ * It is recommended that values here be short (<16 character) alpha-numeric
+ * strings, as they will be used to construct DDB(4) script names.
+ */
+extern const char * volatile kdb_why;
+#define	KDB_WHY_UNSET		NULL		/* No reason set. */
+#define	KDB_WHY_PANIC		"panic"		/* panic() was called. */
+#define	KDB_WHY_SYSCTL		"sysctl"	/* Sysctl entered debugger. */
+#define	KDB_WHY_BOOTFLAGS	"bootflags"	/* Boot flags were set. */
+#define	KDB_WHY_WITNESS		"witness"	/* Witness entered debugger. */
+#define	KDB_WHY_VFSLOCK		"vfslock"	/* VFS detected lock problem. */
+#define	KDB_WHY_NETGRAPH	"netgraph"	/* Netgraph entered debugger. */
+#define	KDB_WHY_BREAK		"break"		/* Console or serial break. */
+#define	KDB_WHY_WATCHDOG	"watchdog"	/* Watchdog entered debugger. */
+#define	KDB_WHY_CAM		"cam"		/* CAM has entered debugger. */
+#define	KDB_WHY_NDIS		"ndis"		/* NDIS entered debugger. */
+#define	KDB_WHY_ACPI		"acpi"		/* ACPI entered debugger. */
+#define	KDB_WHY_TRAPSIG		"trapsig"	/* Sun4v/Sparc fault. */
+#define	KDB_WHY_POWERFAIL	"powerfail"	/* Powerfail NMI. */
+#define	KDB_WHY_MAC		"mac"		/* MAC Framework. */
+#define	KDB_WHY_POWERPC		"powerpc"	/* Unhandled powerpc intr. */
+#define	KDB_WHY_UNIONFS		"unionfs"	/* Unionfs bug. */
+
 #endif /* !_SYS_KDB_H_ */
