[Midnightbsd-cvs] src: sys/ddb:

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Sep 21 11:26:17 EDT 2008


Log Message:
-----------


Modified Files:
--------------
    src/sys/ddb:
        db_access.c (r1.1.1.1 -> r1.2)
        db_command.c (r1.1.1.1 -> r1.2)
        db_examine.c (r1.1.1.1 -> r1.2)
        db_main.c (r1.1.1.1 -> r1.2)
        db_output.c (r1.1.1.1 -> r1.2)
        db_output.h (r1.1.1.1 -> r1.2)
        db_ps.c (r1.1.1.1 -> r1.2)
        db_sym.c (r1.1.1.1 -> r1.2)
        db_thread.c (r1.1.1.1 -> r1.2)
        db_watch.c (r1.1.1.1 -> r1.2)
        ddb.h (r1.1.1.1 -> r1.2)

-------------- next part --------------
Index: db_watch.c
===================================================================
RCS file: /home/cvs/src/sys/ddb/db_watch.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/ddb/db_watch.c -L sys/ddb/db_watch.c -u -r1.1.1.1 -r1.2
--- sys/ddb/db_watch.c
+++ sys/ddb/db_watch.c
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/ddb/db_watch.c,v 1.26 2005/01/06 01:34:41 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/ddb/db_watch.c,v 1.28 2006/11/17 16:41:56 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -66,11 +66,6 @@
 static void		db_set_watchpoint(vm_map_t map, db_addr_t addr,
 				       vm_size_t size);
 
-int  db_md_set_watchpoint(db_expr_t addr, db_expr_t size);
-int  db_md_clr_watchpoint(db_expr_t addr, db_expr_t size);
-void db_md_list_watchpoints(void);
-
-
 static db_watchpoint_t
 db_watchpoint_alloc()
 {
@@ -173,11 +168,19 @@
 	    return;
 	}
 
+#ifdef __LP64__
+	db_printf(" Map                Address          Size\n");
+#else
 	db_printf(" Map        Address  Size\n");
+#endif
 	for (watch = db_watchpoint_list;
 	     watch != 0;
 	     watch = watch->link)
+#ifdef __LP64__
+	    db_printf("%s%16p  %16lx  %lx\n",
+#else
 	    db_printf("%s%8p  %8lx  %lx\n",
+#endif
 		      db_map_current(watch->map) ? "*" : " ",
 		      (void *)watch->map, (long)watch->loaddr,
 		      (long)watch->hiaddr - (long)watch->loaddr);
Index: ddb.h
===================================================================
RCS file: /home/cvs/src/sys/ddb/ddb.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/ddb/ddb.h -L sys/ddb/ddb.h -u -r1.1.1.1 -r1.2
--- sys/ddb/ddb.h
+++ sys/ddb/ddb.h
@@ -27,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/ddb/ddb.h,v 1.39 2005/07/02 23:52:37 marcel Exp $
+ * $FreeBSD: src/sys/ddb/ddb.h,v 1.43 2006/07/12 21:22:43 jhb Exp $
  */
 
 /*
@@ -52,23 +52,24 @@
 typedef void db_cmdfcn_t(db_expr_t addr, boolean_t have_addr, db_expr_t count,
 	    char *modif);
 
-typedef void db_page_calloutfcn_t(void *arg);
-
 #define DB_COMMAND(cmd_name, func_name) \
-	DB_SET(cmd_name, func_name, db_cmd_set, 0, NULL)
+	DB_FUNC(cmd_name, func_name, db_cmd_set, 0, NULL)
 #define DB_SHOW_COMMAND(cmd_name, func_name) \
-	DB_SET(cmd_name, func_name, db_show_cmd_set, 0, NULL)
+	DB_FUNC(cmd_name, func_name, db_show_cmd_set, 0, NULL)
 
-#define DB_SET(cmd_name, func_name, set, flag, more)		\
-static db_cmdfcn_t	func_name;				\
-								\
-static const struct command __CONCAT(func_name,_cmd) = {	\
+#define	DB_SET(cmd_name, func_name, set, flag, more)		\
+static const struct command __CONCAT(cmd_name,_cmd) = {		\
 	__STRING(cmd_name),					\
 	func_name,						\
 	flag,							\
 	more							\
 };								\
-TEXT_SET(set, __CONCAT(func_name,_cmd));			\
+TEXT_SET(set, __CONCAT(cmd_name,_cmd))
+
+#define DB_FUNC(cmd_name, func_name, set, flag, more)		\
+static db_cmdfcn_t	func_name;				\
+								\
+DB_SET(cmd_name, func_name, set, flag, more);			\
 								\
 static void							\
 func_name(addr, have_addr, count, modif)			\
@@ -82,6 +83,7 @@
 extern int db_inst_count;
 extern int db_load_count;
 extern int db_store_count;
+extern volatile int db_pager_quit;
 extern db_expr_t db_radix;
 extern db_expr_t db_max_width;
 extern db_expr_t db_tab_stop_width;
@@ -98,9 +100,14 @@
 int		db_expression(db_expr_t *valuep);
 int		db_get_variable(db_expr_t *valuep);
 void		db_iprintf(const char *,...) __printflike(1, 2);
+struct proc	*db_lookup_proc(db_expr_t addr);
+struct thread	*db_lookup_thread(db_expr_t addr, boolean_t check_pid);
 struct vm_map	*db_map_addr(vm_offset_t);
 boolean_t	db_map_current(struct vm_map *);
 boolean_t	db_map_equal(struct vm_map *, struct vm_map *);
+int		db_md_set_watchpoint(db_expr_t addr, db_expr_t size);
+int		db_md_clr_watchpoint(db_expr_t addr, db_expr_t size);
+void		db_md_list_watchpoints(void);
 void		db_print_loc_and_inst(db_addr_t loc);
 void		db_print_thread(void);
 void		db_printf(const char *fmt, ...) __printflike(1, 2);
@@ -110,8 +117,6 @@
 void		db_restart_at_pc(boolean_t watchpt);
 int		db_set_variable(db_expr_t value);
 void		db_set_watchpoints(void);
-void		db_setup_paging(db_page_calloutfcn_t *callout, void *arg,
-				int maxlines);
 void		db_skip_to_eol(void);
 boolean_t	db_stop_at_pc(boolean_t *is_breakpoint);
 #define		db_strcpy	strcpy
@@ -141,11 +146,17 @@
 db_cmdfcn_t	db_watchpoint_cmd;
 db_cmdfcn_t	db_write_cmd;
 
-db_page_calloutfcn_t db_simple_pager;
-
 /*
  * Command table.
  */
+struct command;
+
+struct command_table {
+	struct command *table;
+	struct command **aux_tablep;
+	struct command **aux_tablep_end;
+};
+
 struct command {
 	char *	name;		/* command name */
 	db_cmdfcn_t *fcn;	/* function to call */
@@ -154,7 +165,7 @@
 #define	CS_MORE		0x2	/* standard syntax, but may have other words
 				 * at end */
 #define	CS_SET_DOT	0x100	/* set dot after command */
-	struct command *more;	/* another level of command */
+	struct command_table *more; /* another level of command */
 };
 
 #endif /* !_DDB_DDB_H_ */
Index: db_output.c
===================================================================
RCS file: /home/cvs/src/sys/ddb/db_output.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/ddb/db_output.c -L sys/ddb/db_output.c -u -r1.1.1.1 -r1.2
--- sys/ddb/db_output.c
+++ sys/ddb/db_output.c
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/ddb/db_output.c,v 1.33 2005/01/06 01:34:41 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/ddb/db_output.c,v 1.37 2006/10/10 06:36:01 bde Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -66,15 +66,15 @@
 	((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width)
 db_expr_t	db_max_width = 79;		/* output line width */
 db_expr_t	db_lines_per_page = 20;		/* lines per page */
+volatile int	db_pager_quit;			/* user requested quit */
 static int	db_newlines;			/* # lines this page */
-static int	db_maxlines = -1;		/* max lines/page when paging */
-static db_page_calloutfcn_t *db_page_callout = NULL;
-static void	*db_page_callout_arg = NULL;
+static int	db_maxlines;			/* max lines/page when paging */
 static int	ddb_use_printf = 0;
 SYSCTL_INT(_debug, OID_AUTO, ddb_use_printf, CTLFLAG_RW, &ddb_use_printf, 0,
     "use printf for all ddb output");
 
 static void	db_putchar(int c, void *arg);
+static void	db_pager(void);
 
 /*
  * Force pending whitespace.
@@ -120,12 +120,10 @@
 			return;
 		if (c == '\r' || c == '\n')
 			db_check_interrupt();
-		if (c == '\n' && db_maxlines > 0 && db_page_callout != NULL) {
+		if (c == '\n' && db_maxlines > 0) {
 			db_newlines++;
-			if (db_newlines >= db_maxlines) {
-				db_maxlines = -1;
-				db_page_callout(db_page_callout_arg);
-			}
+			if (db_newlines >= db_maxlines)
+				db_pager();
 		}
 		return;
 	}
@@ -144,22 +142,18 @@
 	}
 	else if (c == '\n') {
 	    /* Newline */
-	    db_force_whitespace();
 	    cnputc(c);
 	    db_output_position = 0;
 	    db_last_non_space = 0;
 	    db_check_interrupt();
-	    if (db_maxlines > 0 && db_page_callout != NULL) {
+	    if (db_maxlines > 0) {
 		    db_newlines++;
-		    if (db_newlines >= db_maxlines) {
-			    db_maxlines = -1;
-			    db_page_callout(db_page_callout_arg);
-		    }
+		    if (db_newlines >= db_maxlines)
+			    db_pager();
 	    }
 	}
 	else if (c == '\r') {
 	    /* Return */
-	    db_force_whitespace();
 	    cnputc(c);
 	    db_output_position = 0;
 	    db_last_non_space = 0;
@@ -181,24 +175,34 @@
 }
 
 /*
- * Register callout for providing a pager for output.
+ * Turn on the pager.
  */
 void
-db_setup_paging(db_page_calloutfcn_t *callout, void *arg, int maxlines)
+db_enable_pager(void)
 {
+	if (db_maxlines == 0) {
+		db_maxlines = db_lines_per_page;
+		db_newlines = 0;
+		db_pager_quit = 0;
+	}
+}
 
-	db_page_callout = callout;
-	db_page_callout_arg = arg;
-	db_maxlines = maxlines;
-	db_newlines = 0;
+/*
+ * Turn off the pager.
+ */
+void
+db_disable_pager(void)
+{
+	db_maxlines = 0;
 }
 
 /*
- * A simple paging callout function.  If the argument is not null, it
- * points to an integer that will be set to 1 if the user asks to quit.
+ * A simple paging callout function.  It supports several simple more(1)-like
+ * commands as well as a quit command that sets db_pager_quit which db
+ * commands can poll to see if they should terminate early.
  */
 void
-db_simple_pager(void *arg)
+db_pager(void)
 {
 	int c, done;
 
@@ -211,20 +215,18 @@
 		case 'j':
 		case '\n':
 			/* Just one more line. */
-			db_setup_paging(db_simple_pager, arg, 1);
+			db_maxlines = 1;
 			done++;
 			break;
 		case 'd':
 			/* Half a page. */
-			db_setup_paging(db_simple_pager, arg,
-			    db_lines_per_page / 2);
+			db_maxlines = db_lines_per_page / 2;
 			done++;
 			break;
 		case 'f':
 		case ' ':
 			/* Another page. */
-			db_setup_paging(db_simple_pager, arg,
-			    db_lines_per_page);
+			db_maxlines = db_lines_per_page;
 			done++;
 			break;
 		case 'q':
@@ -232,11 +234,10 @@
 		case 'x':
 		case 'X':
 			/* Quit */
-			if (arg != NULL) {
-				*(int *)arg = 1;
-				done++;
-				break;
-			}
+			db_maxlines = 0;
+			db_pager_quit = 1;
+			done++;
+			break;
 #if 0
 			/* FALLTHROUGH */
 		default:
@@ -244,7 +245,10 @@
 #endif
 		}
 	}
-	db_printf("        \r");
+	db_printf("        ");
+	db_force_whitespace();
+	db_printf("\r");
+	db_newlines = 0;
 }
 
 /*
@@ -300,8 +304,8 @@
  * End line if too long.
  */
 void
-db_end_line()
+db_end_line(int field_width)
 {
-	if (db_output_position >= db_max_width)
+	if (db_output_position + field_width > db_max_width)
 	    db_printf("\n");
 }
Index: db_main.c
===================================================================
RCS file: /home/cvs/src/sys/ddb/db_main.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/ddb/db_main.c -L sys/ddb/db_main.c -u -r1.1.1.1 -r1.2
--- sys/ddb/db_main.c
+++ sys/ddb/db_main.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/ddb/db_main.c,v 1.4 2005/01/06 01:34:41 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/ddb/db_main.c,v 1.5 2006/11/06 11:10:57 kib Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -47,8 +47,9 @@
 
 static dbbe_init_f db_init;
 static dbbe_trap_f db_trap;
+static dbbe_trace_f db_trace_self_wrapper;
 
-KDB_BACKEND(ddb, db_init, db_trace_self, db_trap);
+KDB_BACKEND(ddb, db_init, db_trace_self_wrapper, db_trap);
 
 vm_offset_t ksym_start, ksym_end;
 
@@ -226,3 +227,15 @@
 
 	return (1);
 }
+
+static void
+db_trace_self_wrapper(void)
+{
+	jmp_buf jb;
+	void *prev_jb;
+
+	prev_jb = kdb_jmpbuf(jb);
+	if (setjmp(jb) == 0)
+		db_trace_self();
+	(void)kdb_jmpbuf(prev_jb);
+}
Index: db_access.c
===================================================================
RCS file: /home/cvs/src/sys/ddb/db_access.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/ddb/db_access.c -L sys/ddb/db_access.c -u -r1.1.1.1 -r1.2
--- sys/ddb/db_access.c
+++ sys/ddb/db_access.c
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/ddb/db_access.c,v 1.19 2005/01/06 01:34:41 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/ddb/db_access.c,v 1.20 2005/12/04 02:12:39 ru Exp $");
 
 #include <sys/param.h>
 #include <sys/kdb.h>
@@ -49,6 +49,10 @@
 	0xFF800000U
 };
 
+#ifndef BYTE_MSF
+#define	BYTE_MSF	0
+#endif
+
 db_expr_t
 db_get_value(addr, size, is_signed)
 	db_addr_t	addr;
Index: db_sym.c
===================================================================
RCS file: /home/cvs/src/sys/ddb/db_sym.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/ddb/db_sym.c -L sys/ddb/db_sym.c -u -r1.1.1.1 -r1.2
--- sys/ddb/db_sym.c
+++ sys/ddb/db_sym.c
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/ddb/db_sym.c,v 1.36 2005/01/06 01:34:41 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/ddb/db_sym.c,v 1.37 2006/06/16 16:17:52 kib Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -230,7 +230,6 @@
 	c_db_sym_t	ret = C_DB_SYM_NULL, sym;
 
 	newdiff = diff = ~0;
-	db_last_symtab = 0;
 	for (i = 0; i < db_nsymtab; i++) {
 	    sym = X_db_search_symbol(&db_symtabs[i], val, strategy, &newdiff);
 	    if (newdiff < diff) {
Index: db_command.c
===================================================================
RCS file: /home/cvs/src/sys/ddb/db_command.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/ddb/db_command.c -L sys/ddb/db_command.c -u -r1.1.1.1 -r1.2
--- sys/ddb/db_command.c
+++ sys/ddb/db_command.c
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/ddb/db_command.c,v 1.60.2.2 2005/10/25 20:10:56 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/ddb/db_command.c,v 1.73 2007/01/17 15:05:51 delphij Exp $");
 
 #include <sys/param.h>
 #include <sys/linker_set.h>
@@ -68,14 +68,89 @@
 
 static db_cmdfcn_t	db_fncall;
 static db_cmdfcn_t	db_gdb;
+static db_cmdfcn_t	db_halt;
 static db_cmdfcn_t	db_kill;
 static db_cmdfcn_t	db_reset;
 static db_cmdfcn_t	db_stack_trace;
 static db_cmdfcn_t	db_stack_trace_all;
 static db_cmdfcn_t	db_watchdog;
 
-/* XXX this is actually forward-static. */
-extern struct command	db_show_cmds[];
+/*
+ * 'show' commands
+ */
+
+static struct command db_show_all_cmds[] = {
+	{ "procs",	db_ps,			0,	0 },
+	{ (char *)0 }
+};
+
+static struct command_table db_show_all_table = {
+	db_show_all_cmds
+};
+
+static struct command db_show_cmds[] = {
+	{ "all",	0,			0,	&db_show_all_table },
+	{ "registers",	db_show_regs,		0,	0 },
+	{ "breaks",	db_listbreak_cmd, 	0,	0 },
+	{ "threads",	db_show_threads,	0,	0 },
+	{ (char *)0, }
+};
+
+static struct command_table db_show_table = {
+	db_show_cmds,
+	SET_BEGIN(db_show_cmd_set),
+	SET_LIMIT(db_show_cmd_set)
+};
+	
+static struct command db_commands[] = {
+	{ "print",	db_print_cmd,		0,	0 },
+	{ "p",		db_print_cmd,		0,	0 },
+	{ "examine",	db_examine_cmd,		CS_SET_DOT, 0 },
+	{ "x",		db_examine_cmd,		CS_SET_DOT, 0 },
+	{ "search",	db_search_cmd,		CS_OWN|CS_SET_DOT, 0 },
+	{ "set",	db_set_cmd,		CS_OWN,	0 },
+	{ "write",	db_write_cmd,		CS_MORE|CS_SET_DOT, 0 },
+	{ "w",		db_write_cmd,		CS_MORE|CS_SET_DOT, 0 },
+	{ "delete",	db_delete_cmd,		0,	0 },
+	{ "d",		db_delete_cmd,		0,	0 },
+	{ "break",	db_breakpoint_cmd,	0,	0 },
+	{ "b",		db_breakpoint_cmd,	0,	0 },
+	{ "dwatch",	db_deletewatch_cmd,	0,	0 },
+	{ "watch",	db_watchpoint_cmd,	CS_MORE,0 },
+	{ "dhwatch",	db_deletehwatch_cmd,	0,      0 },
+	{ "hwatch",	db_hwatchpoint_cmd,	0,      0 },
+	{ "step",	db_single_step_cmd,	0,	0 },
+	{ "s",		db_single_step_cmd,	0,	0 },
+	{ "continue",	db_continue_cmd,	0,	0 },
+	{ "c",		db_continue_cmd,	0,	0 },
+	{ "until",	db_trace_until_call_cmd,0,	0 },
+	{ "next",	db_trace_until_matching_cmd,0,	0 },
+	{ "match",	db_trace_until_matching_cmd,0,	0 },
+	{ "trace",	db_stack_trace,		CS_OWN,	0 },
+	{ "t",		db_stack_trace,		CS_OWN,	0 },
+	{ "alltrace",	db_stack_trace_all,	0,	0 },
+	{ "where",	db_stack_trace,		CS_OWN,	0 },
+	{ "bt",		db_stack_trace,		CS_OWN,	0 },
+	{ "call",	db_fncall,		CS_OWN,	0 },
+	{ "show",	0,			0,	&db_show_table },
+	{ "ps",		db_ps,			0,	0 },
+	{ "gdb",	db_gdb,			0,	0 },
+	{ "halt",	db_halt,		0,	0 },
+	{ "reboot",	db_reset,		0,	0 },
+	{ "reset",	db_reset,		0,	0 },
+	{ "kill",	db_kill,		CS_OWN,	0 },
+	{ "watchdog",	db_watchdog,		0,	0 },
+	{ "thread",	db_set_thread,		CS_OWN,	0 },
+	{ (char *)0, }
+};
+
+static struct command_table db_command_table = {
+	db_commands,
+	SET_BEGIN(db_cmd_set),
+	SET_LIMIT(db_cmd_set)
+};
+
+static struct command	*db_last_command = 0;
 
 /*
  * if 'ed' style: 'dot' is set at start of last item printed,
@@ -105,94 +180,81 @@
 #define	CMD_AMBIGUOUS	3
 #define	CMD_HELP	4
 
-static void	db_cmd_list(struct command *table, struct command **aux_tablep,
-		    struct command **aux_tablep_end);
-static int	db_cmd_search(char *name, struct command *table,
-		    struct command **aux_tablep,
-		    struct command **aux_tablep_end, struct command **cmdp);
+static void	db_cmd_match(char *name, struct command *cmd,
+		    struct command **cmdp, int *resultp);
+static void	db_cmd_list(struct command_table *table);
+static int	db_cmd_search(char *name, struct command_table *table,
+		    struct command **cmdp);
 static void	db_command(struct command **last_cmdp,
-		    struct command *cmd_table, struct command **aux_cmd_tablep,
-		    struct command **aux_cmd_tablep_end);
+		    struct command_table *cmd_table);
 
 /*
- * Search for command prefix.
+ * Helper function to match a single command.
  */
-static int
-db_cmd_search(name, table, aux_tablep, aux_tablep_end, cmdp)
+static void
+db_cmd_match(name, cmd, cmdp, resultp)
 	char *		name;
-	struct command	*table;
-	struct command	**aux_tablep;
-	struct command	**aux_tablep_end;
+	struct command	*cmd;
 	struct command	**cmdp;	/* out */
+	int *		resultp;
 {
-	struct command	*cmd;
-	struct command	**aux_cmdp;
-	int		result = CMD_NONE;
+	char *lp, *rp;
+	int c;
 
-	for (cmd = table; cmd->name != 0; cmd++) {
-	    register char *lp;
-	    register char *rp;
-	    register int  c;
-
-	    lp = name;
-	    rp = cmd->name;
-	    while ((c = *lp) == *rp) {
+	lp = name;
+	rp = cmd->name;
+	while ((c = *lp) == *rp) {
 		if (c == 0) {
-		    /* complete match */
-		    *cmdp = cmd;
-		    return (CMD_UNIQUE);
+			/* complete match */
+			*cmdp = cmd;
+			*resultp = CMD_UNIQUE;
+			return;
 		}
 		lp++;
 		rp++;
-	    }
-	    if (c == 0) {
+	}
+	if (c == 0) {
 		/* end of name, not end of command -
 		   partial match */
-		if (result == CMD_FOUND) {
-		    result = CMD_AMBIGUOUS;
-		    /* but keep looking for a full match -
-		       this lets us match single letters */
-		}
-		else {
-		    *cmdp = cmd;
-		    result = CMD_FOUND;
+		if (*resultp == CMD_FOUND) {
+			*resultp = CMD_AMBIGUOUS;
+			/* but keep looking for a full match -
+			   this lets us match single letters */
+		} else {
+			*cmdp = cmd;
+			*resultp = CMD_FOUND;
 		}
-	    }
 	}
-	if (result == CMD_NONE && aux_tablep != 0)
-	    /* XXX repeat too much code. */
-	    for (aux_cmdp = aux_tablep; aux_cmdp < aux_tablep_end; aux_cmdp++) {
-		register char *lp;
-		register char *rp;
-		register int  c;
-
-		lp = name;
-		rp = (*aux_cmdp)->name;
-		while ((c = *lp) == *rp) {
-		    if (c == 0) {
-			/* complete match */
-			*cmdp = *aux_cmdp;
+}
+
+/*
+ * Search for command prefix.
+ */
+static int
+db_cmd_search(name, table, cmdp)
+	char *		name;
+	struct command_table *table;
+	struct command	**cmdp;	/* out */
+{
+	struct command	*cmd;
+	struct command	**aux_cmdp;
+	int		result = CMD_NONE;
+
+	for (cmd = table->table; cmd->name != 0; cmd++) {
+		db_cmd_match(name, cmd, cmdp, &result);
+		if (result == CMD_UNIQUE)
 			return (CMD_UNIQUE);
-		    }
-		    lp++;
-		    rp++;
-		}
-		if (c == 0) {
-		    /* end of name, not end of command -
-		       partial match */
-		    if (result == CMD_FOUND) {
-			result = CMD_AMBIGUOUS;
-			/* but keep looking for a full match -
-			   this lets us match single letters */
-		    }
-		    else {
-			*cmdp = *aux_cmdp;
-			result = CMD_FOUND;
-		    }
+	}
+	if (table->aux_tablep != NULL)
+		for (aux_cmdp = table->aux_tablep;
+		     aux_cmdp < table->aux_tablep_end;
+		     aux_cmdp++) {
+			db_cmd_match(name, *aux_cmdp, cmdp, &result);
+			if (result == CMD_UNIQUE)
+				return (CMD_UNIQUE);
 		}
-	    }
 	if (result == CMD_NONE) {
-	    /* check for 'help' */
+		/* check for 'help' */
 		if (name[0] == 'h' && name[1] == 'e'
 		    && name[2] == 'l' && name[3] == 'p')
 			result = CMD_HELP;
@@ -201,32 +263,29 @@
 }
 
 static void
-db_cmd_list(table, aux_tablep, aux_tablep_end)
-	struct command *table;
-	struct command **aux_tablep;
-	struct command **aux_tablep_end;
+db_cmd_list(table)
+	struct command_table *table;
 {
 	register struct command *cmd;
 	register struct command **aux_cmdp;
 
-	for (cmd = table; cmd->name != 0; cmd++) {
+	for (cmd = table->table; cmd->name != 0; cmd++) {
 	    db_printf("%-12s", cmd->name);
-	    db_end_line();
+	    db_end_line(12);
 	}
-	if (aux_tablep == 0)
+	if (table->aux_tablep == NULL)
 	    return;
-	for (aux_cmdp = aux_tablep; aux_cmdp < aux_tablep_end; aux_cmdp++) {
+	for (aux_cmdp = table->aux_tablep; aux_cmdp < table->aux_tablep_end;
+	     aux_cmdp++) {
 	    db_printf("%-12s", (*aux_cmdp)->name);
-	    db_end_line();
+	    db_end_line(12);
 	}
 }
 
 static void
-db_command(last_cmdp, cmd_table, aux_cmd_tablep, aux_cmd_tablep_end)
+db_command(last_cmdp, cmd_table)
 	struct command	**last_cmdp;	/* IN_OUT */
-	struct command	*cmd_table;
-	struct command	**aux_cmd_tablep;
-	struct command	**aux_cmd_tablep_end;
+	struct command_table *cmd_table;
 {
 	struct command	*cmd;
 	int		t;
@@ -260,8 +319,6 @@
 	    while (cmd_table) {
 		result = db_cmd_search(db_tok_string,
 				       cmd_table,
-				       aux_cmd_tablep,
-				       aux_cmd_tablep_end,
 				       &cmd);
 		switch (result) {
 		    case CMD_NONE:
@@ -273,23 +330,16 @@
 			db_flush_lex();
 			return;
 		    case CMD_HELP:
-			db_cmd_list(cmd_table, aux_cmd_tablep, aux_cmd_tablep_end);
+			db_cmd_list(cmd_table);
 			db_flush_lex();
 			return;
 		    default:
 			break;
 		}
-		if ((cmd_table = cmd->more) != 0) {
-		    /* XXX usually no more aux's. */
-		    aux_cmd_tablep = 0;
-		    if (cmd_table == db_show_cmds) {
-			aux_cmd_tablep = SET_BEGIN(db_show_cmd_set);
-			aux_cmd_tablep_end = SET_LIMIT(db_show_cmd_set);
-		    }
-
+		if ((cmd_table = cmd->more) != NULL) {
 		    t = db_read_token();
 		    if (t != tIDENT) {
-			db_cmd_list(cmd_table, aux_cmd_tablep, aux_cmd_tablep_end);
+			db_cmd_list(cmd_table);
 			db_flush_lex();
 			return;
 		    }
@@ -347,8 +397,9 @@
 	    /*
 	     * Execute the command.
 	     */
+	    db_enable_pager();
 	    (*cmd->fcn)(addr, have_addr, count, modif);
-	    db_setup_paging(NULL, NULL, -1);
+	    db_disable_pager();
 
 	    if (cmd->flag & CS_SET_DOT) {
 		/*
@@ -373,68 +424,12 @@
 }
 
 /*
- * 'show' commands
- */
-
-static struct command db_show_all_cmds[] = {
-	{ "procs",	db_ps,			0,	0 },
-	{ (char *)0 }
-};
-
-static struct command db_show_cmds[] = {
-	{ "all",	0,			0,	db_show_all_cmds },
-	{ "registers",	db_show_regs,		0,	0 },
-	{ "breaks",	db_listbreak_cmd, 	0,	0 },
-	{ "threads",	db_show_threads,	0,	0 },
-	{ (char *)0, }
-};
-
-static struct command db_command_table[] = {
-	{ "print",	db_print_cmd,		0,	0 },
-	{ "p",		db_print_cmd,		0,	0 },
-	{ "examine",	db_examine_cmd,		CS_SET_DOT, 0 },
-	{ "x",		db_examine_cmd,		CS_SET_DOT, 0 },
-	{ "search",	db_search_cmd,		CS_OWN|CS_SET_DOT, 0 },
-	{ "set",	db_set_cmd,		CS_OWN,	0 },
-	{ "write",	db_write_cmd,		CS_MORE|CS_SET_DOT, 0 },
-	{ "w",		db_write_cmd,		CS_MORE|CS_SET_DOT, 0 },
-	{ "delete",	db_delete_cmd,		0,	0 },
-	{ "d",		db_delete_cmd,		0,	0 },
-	{ "break",	db_breakpoint_cmd,	0,	0 },
-	{ "dwatch",	db_deletewatch_cmd,	0,	0 },
-	{ "watch",	db_watchpoint_cmd,	CS_MORE,0 },
-	{ "dhwatch",	db_deletehwatch_cmd,	0,      0 },
-	{ "hwatch",	db_hwatchpoint_cmd,	0,      0 },
-	{ "step",	db_single_step_cmd,	0,	0 },
-	{ "s",		db_single_step_cmd,	0,	0 },
-	{ "continue",	db_continue_cmd,	0,	0 },
-	{ "c",		db_continue_cmd,	0,	0 },
-	{ "until",	db_trace_until_call_cmd,0,	0 },
-	{ "next",	db_trace_until_matching_cmd,0,	0 },
-	{ "match",	db_trace_until_matching_cmd,0,	0 },
-	{ "trace",	db_stack_trace,		CS_OWN,	0 },
-	{ "alltrace",	db_stack_trace_all,	0,	0 },
-	{ "where",	db_stack_trace,		CS_OWN,	0 },
-	{ "bt",		db_stack_trace,		CS_OWN,	0 },
-	{ "call",	db_fncall,		CS_OWN,	0 },
-	{ "show",	0,			0,	db_show_cmds },
-	{ "ps",		db_ps,			0,	0 },
-	{ "gdb",	db_gdb,			0,	0 },
-	{ "reset",	db_reset,		0,	0 },
-	{ "kill",	db_kill,		CS_OWN,	0 },
-	{ "watchdog",	db_watchdog,		0,	0 },
-	{ "thread",	db_set_thread,		CS_OWN,	0 },
-	{ (char *)0, }
-};
-
-static struct command	*db_last_command = 0;
-
-/*
  * At least one non-optional command must be implemented using
  * DB_COMMAND() so that db_cmd_set gets created.  Here is one.
  */
 DB_COMMAND(panic, db_panic)
 {
+	db_disable_pager();
 	panic("from debugger");
 }
 
@@ -455,8 +450,7 @@
 	    db_printf("db> ");
 	    (void) db_read_line();
 
-	    db_command(&db_last_command, db_command_table,
-		       SET_BEGIN(db_cmd_set), SET_LIMIT(db_cmd_set));
+	    db_command(&db_last_command, &db_command_table);
 	}
 }
 
@@ -539,12 +533,20 @@
 	    }
 	}
 	db_skip_to_eol();
+	db_disable_pager();
 
 	if (DB_CALL(fn_addr, &retval, nargs, args))
 		db_printf("= %#lr\n", (long)retval);
 }
 
 static void
+db_halt(db_expr_t dummy, boolean_t dummy2, db_expr_t dummy3, char *dummy4)
+{
+
+	cpu_halt();
+}
+
+static void
 db_kill(dummy1, dummy2, dummy3, dummy4)
 	db_expr_t	dummy1;
 	boolean_t	dummy2;
@@ -577,7 +579,7 @@
 	 * since we're in DDB.
 	 */
 	/* sx_slock(&allproc_lock); */
-	LIST_FOREACH(p, &allproc, p_list)
+	FOREACH_PROC_IN_SYSTEM(p)
 	    if (p->p_pid == pid)
 		    break;
 	/* sx_sunlock(&allproc_lock); */
@@ -688,12 +690,22 @@
 {
 	struct proc *p;
 	struct thread *td;
+	jmp_buf jb;
+	void *prev_jb;
 
-	for (p = LIST_FIRST(&allproc); p != NULL; p = LIST_NEXT(p, p_list)) {
-		FOREACH_THREAD_IN_PROC(p, td) {
-			db_printf("\nTracing command %s pid %d tid %ld td %p\n",
-			    p->p_comm, p->p_pid, (long)td->td_tid, td);
-			db_trace_thread(td, -1);
+	FOREACH_PROC_IN_SYSTEM(p) {
+		prev_jb = kdb_jmpbuf(jb);
+		if (setjmp(jb) == 0) {
+			FOREACH_THREAD_IN_PROC(p, td) {
+				db_printf("\nTracing command %s pid %d tid %ld td %p\n",
+					  p->p_comm, p->p_pid, (long)td->td_tid, td);
+				db_trace_thread(td, -1);
+				if (db_pager_quit) {
+					kdb_jmpbuf(prev_jb);
+					return;
+				}
+			}
 		}
+		kdb_jmpbuf(prev_jb);
 	}
 }
Index: db_output.h
===================================================================
RCS file: /home/cvs/src/sys/ddb/db_output.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/ddb/db_output.h -L sys/ddb/db_output.h -u -r1.1.1.1 -r1.2
--- sys/ddb/db_output.h
+++ sys/ddb/db_output.h
@@ -23,7 +23,7 @@
  * any improvements or extensions that they make and grant Carnegie the
  * rights to redistribute these changes.
  *
- * $FreeBSD: src/sys/ddb/db_output.h,v 1.13 2005/01/06 01:34:41 imp Exp $
+ * $FreeBSD: src/sys/ddb/db_output.h,v 1.15 2006/10/08 18:15:08 bde Exp $
  */
 
 #ifndef _DDB_DB_OUTPUT_H_
@@ -38,7 +38,9 @@
  * Printing routines for kernel debugger.
  */
 
-void	db_end_line(void);
+void	db_disable_pager(void);
+void	db_enable_pager(void);
+void	db_end_line(int);
 void	db_force_whitespace(void);
 int	db_print_position(void);
 
Index: db_examine.c
===================================================================
RCS file: /home/cvs/src/sys/ddb/db_examine.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/ddb/db_examine.c -L sys/ddb/db_examine.c -u -r1.1.1.1 -r1.2
--- sys/ddb/db_examine.c
+++ sys/ddb/db_examine.c
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/ddb/db_examine.c,v 1.32 2005/01/06 01:34:41 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/ddb/db_examine.c,v 1.33.2.1 2007/11/08 20:25:47 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -80,7 +80,7 @@
 	int		width;
 	char *		fp;
 
-	while (--count >= 0) {
+	while (--count >= 0 && !db_pager_quit) {
 	    fp = fmt;
 	    size = 4;
 	    while ((c = *fp++) != 0) {
@@ -176,7 +176,7 @@
 				break;
 			}
 			if (db_print_position() != 0)
-			    db_end_line();
+			    db_end_line(1);
 			break;
 		}
 	    }
Index: db_thread.c
===================================================================
RCS file: /home/cvs/src/sys/ddb/db_thread.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/ddb/db_thread.c -L sys/ddb/db_thread.c -u -r1.1.1.1 -r1.2
--- sys/ddb/db_thread.c
+++ sys/ddb/db_thread.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/ddb/db_thread.c,v 1.4 2005/01/06 01:34:41 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/ddb/db_thread.c,v 1.7 2007/01/17 15:05:51 delphij Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -38,6 +38,8 @@
 #include <ddb/db_command.h>
 #include <ddb/db_sym.h>
 
+static db_expr_t hex2dec(db_expr_t expr);
+
 void
 db_print_thread(void)
 {
@@ -91,13 +93,9 @@
 	jmp_buf jb;
 	void *prev_jb;
 	struct thread *thr;
-	int pager_quit;
-
-	db_setup_paging(db_simple_pager, &pager_quit, db_lines_per_page);
 
-	pager_quit = 0;
 	thr = kdb_thr_first();
-	while (!pager_quit && thr != NULL) {
+	while (!db_pager_quit && thr != NULL) {
 		db_printf("  %6ld (%p)  ", (long)thr->td_tid, thr);
 		prev_jb = kdb_jmpbuf(jb);
 		if (setjmp(jb) == 0) {
@@ -108,3 +106,93 @@
 		thr = kdb_thr_next(thr);
 	}
 }
+
+/*
+ * Take the parsed expression value from the command line that was parsed
+ * as a hexadecimal value and convert it as if the expression was parsed
+ * as a decimal value.  Returns -1 if the expression was not a valid
+ * decimal value.
+ */
+static db_expr_t
+hex2dec(db_expr_t expr)
+{
+	uintptr_t x, y;
+	db_expr_t val;
+
+	y = 1;
+	val = 0;
+	x = expr;
+	while (x != 0) {
+		if (x % 16 > 9)
+			return (-1);
+		val += (x % 16) * (y);
+		x >>= 4;
+		y *= 10;
+	}
+	return (val);
+}
+
+/*
+ * Lookup a thread based on a db expression address.  We assume that the
+ * address was parsed in hexadecimal.  We reparse the address in decimal
+ * first and try to treat it as a thread ID to find an associated thread.
+ * If that fails and check_pid is true, we terat the decimal value as a
+ * PID.  If that matches a process, we return the first thread in that
+ * process.  Otherwise, we treat the addr as a pointer to a thread.
+ */
+struct thread *
+db_lookup_thread(db_expr_t addr, boolean_t check_pid)
+{
+	struct thread *td;
+	db_expr_t decaddr;
+	struct proc *p;
+
+	/*
+	 * If the parsed address was not a valid decimal expression,
+	 * assume it is a thread pointer.
+	 */
+	decaddr = hex2dec(addr);
+	if (decaddr == -1)
+		return ((struct thread *)addr);
+
+	td = kdb_thr_lookup(decaddr);
+	if (td != NULL)
+		return (td);
+	if (check_pid) {
+		FOREACH_PROC_IN_SYSTEM(p) {
+			if (p->p_pid == decaddr)
+				return (FIRST_THREAD_IN_PROC(p));
+		}
+		LIST_FOREACH(p, &zombproc, p_list) {
+			if (p->p_pid == decaddr)
+				return (FIRST_THREAD_IN_PROC(p));
+		}
+	}
+	return ((struct thread *)addr);
+}
+
+/*
+ * Lookup a process based on a db expression address.  We assume that the
+ * address was parsed in hexadecimal.  We reparse the address in decimal
+ * first and try to treat it as a PID to find an associated process.
+ * If that fails we treat the addr as a pointer to a process.
+ */
+struct proc *
+db_lookup_proc(db_expr_t addr)
+{
+	db_expr_t decaddr;
+	struct proc *p;
+
+	decaddr = hex2dec(addr);
+	if (decaddr != -1) {
+		FOREACH_PROC_IN_SYSTEM(p) {
+			if (p->p_pid == decaddr)
+				return (p);
+		}
+		LIST_FOREACH(p, &zombproc, p_list) {
+			if (p->p_pid == decaddr)
+				return (p);
+		}
+	}
+	return ((struct proc *)addr);
+}
Index: db_ps.c
===================================================================
RCS file: /home/cvs/src/sys/ddb/db_ps.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/ddb/db_ps.c -L sys/ddb/db_ps.c -u -r1.1.1.1 -r1.2
--- sys/ddb/db_ps.c
+++ sys/ddb/db_ps.c
@@ -28,143 +28,385 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/ddb/db_ps.c,v 1.55 2004/11/20 02:32:42 das Exp $");
+__FBSDID("$FreeBSD: src/sys/ddb/db_ps.c,v 1.66 2007/09/17 05:27:19 jeff Exp $");
 
 #include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
 #include <sys/cons.h>
+#include <sys/jail.h>
+#include <sys/kdb.h>
+#include <sys/linker_set.h>
+#include <sys/proc.h>
+#include <sys/sysent.h>
+#include <sys/systm.h>
 #include <vm/vm.h>
 #include <vm/vm_param.h>
 #include <vm/pmap.h>
 
 #include <ddb/ddb.h>
 
-static void	dumpthread(volatile struct proc *p, volatile struct thread *td);
+static void	dumpthread(volatile struct proc *p, volatile struct thread *td,
+		    int all);
 
+/*
+ * Layout:
+ * - column counts
+ * - header
+ * - single-threaded process
+ * - multi-threaded process
+ * - thread in a MT process
+ *
+ *          1         2         3         4         5         6         7
+ * 1234567890123456789012345678901234567890123456789012345678901234567890
+ *   pid  ppid  pgrp   uid   state   wmesg     wchan    cmd
+ * <pid> <ppi> <pgi> <uid>  <stat> < wmesg > < wchan  > <name>
+ * <pid> <ppi> <pgi> <uid>  <stat>  (threaded)          <command>
+ * <tid >                   <stat> < wmesg > < wchan  > <name>
+ *
+ * For machines with 64-bit pointers, we expand the wchan field 8 more
+ * characters.
+ */
 void
-db_ps(dummy1, dummy2, dummy3, dummy4)
-	db_expr_t	dummy1;
-	boolean_t	dummy2;
-	db_expr_t	dummy3;
-	char *		dummy4;
+db_ps(db_expr_t addr, boolean_t hasaddr, db_expr_t count, char *modif)
 {
 	volatile struct proc *p, *pp;
 	volatile struct thread *td;
-	char *state;
-	int np, quit;
+	struct ucred *cred;
+	struct pgrp *pgrp;
+	char state[9];
+	int np, rflag, sflag, dflag, lflag, wflag;
 
 	np = nprocs;
-	quit = 0;
 
-	/* sx_slock(&allproc_lock); */
 	if (!LIST_EMPTY(&allproc))
 		p = LIST_FIRST(&allproc);
 	else
 		p = &proc0;
 
-	db_setup_paging(db_simple_pager, &quit, db_lines_per_page);
-	db_printf("  pid   proc     uid  ppid  pgrp  flag   stat  wmesg    wchan  cmd\n");
-	while (--np >= 0 && !quit) {
+#ifdef __LP64__
+	db_printf("  pid  ppid  pgrp   uid   state   wmesg         wchan        cmd\n");
+#else
+	db_printf("  pid  ppid  pgrp   uid   state   wmesg     wchan    cmd\n");
+#endif
+	while (--np >= 0 && !db_pager_quit) {
 		if (p == NULL) {
-			printf("oops, ran out of processes early!\n");
+			db_printf("oops, ran out of processes early!\n");
 			break;
 		}
-		/* PROC_LOCK(p); */
 		pp = p->p_pptr;
 		if (pp == NULL)
 			pp = p;
 
+		cred = p->p_ucred;
+		pgrp = p->p_pgrp;
+		db_printf("%5d %5d %5d %5d ", p->p_pid, pp->p_pid,
+		    pgrp != NULL ? pgrp->pg_id : 0,
+		    cred != NULL ? cred->cr_ruid : 0);
 
-		switch(p->p_state) {
+		/* Determine our primary process state. */
+		switch (p->p_state) {
 		case PRS_NORMAL:
 			if (P_SHOULDSTOP(p))
-				state = "stop";
-			else
-				state = "";
+				state[0] = 'T';
+			else {
+				/*
+				 * One of D, L, R, S, W.  For a
+				 * multithreaded process we will use
+				 * the state of the thread with the
+				 * highest precedence.  The
+				 * precendence order from high to low
+				 * is R, L, D, S, W.  If no thread is
+				 * in a sane state we use '?' for our
+				 * primary state.
+				 */
+				rflag = sflag = dflag = lflag = wflag = 0;
+				FOREACH_THREAD_IN_PROC(p, td) {
+					if (td->td_state == TDS_RUNNING ||
+					    td->td_state == TDS_RUNQ ||
+					    td->td_state == TDS_CAN_RUN)
+						rflag++;
+					if (TD_ON_LOCK(td))
+						lflag++;
+					if (TD_IS_SLEEPING(td)) {
+						if (!td->td_flags & TDF_SINTR)
+							dflag++;
+						else
+							sflag++;
+					}
+					if (TD_AWAITING_INTR(td))
+						wflag++;
+				}
+				if (rflag)
+					state[0] = 'R';
+				else if (lflag)
+					state[0] = 'L';
+				else if (dflag)
+					state[0] = 'D';
+				else if (sflag)
+					state[0] = 'S';
+				else if (wflag)
+					state[0] = 'W';
+				else
+					state[0] = '?';				
+			}
 			break;
 		case PRS_NEW:
-			state = "new ";
+			state[0] = 'N';
 			break;
 		case PRS_ZOMBIE:
-			state = "zomb";
+			state[0] = 'Z';
 			break;
 		default:
-			state = "Unkn";
+			state[0] = 'U';
 			break;
 		}
-		db_printf("%5d %8p %4d %5d %5d %07x %s",
-		    p->p_pid, (volatile void *)p,
-		    p->p_ucred != NULL ? p->p_ucred->cr_ruid : 0, pp->p_pid,
-		    p->p_pgrp != NULL ? p->p_pgrp->pg_id : 0, p->p_flag,
-		    state);
+		state[1] = '\0';
+
+		/* Additional process state flags. */
+		if (!p->p_flag & P_INMEM)
+			strlcat(state, "W", sizeof(state));
+		if (p->p_flag & P_TRACED)
+			strlcat(state, "X", sizeof(state));
+		if (p->p_flag & P_WEXIT && p->p_state != PRS_ZOMBIE)
+			strlcat(state, "E", sizeof(state));
+		if (p->p_flag & P_PPWAIT)
+			strlcat(state, "V", sizeof(state));
+		if (p->p_flag & P_SYSTEM || p->p_lock > 0)
+			strlcat(state, "L", sizeof(state));
+		if (p->p_session != NULL && SESS_LEADER(p))
+			strlcat(state, "s", sizeof(state));
+		/* Cheated here and didn't compare pgid's. */
+		if (p->p_flag & P_CONTROLT)
+			strlcat(state, "+", sizeof(state));
+		if (cred != NULL && jailed(cred))
+			strlcat(state, "J", sizeof(state));
+		db_printf(" %-6.6s ", state);
 		if (p->p_flag & P_HADTHREADS)
-			db_printf("(threaded)  %s\n", p->p_comm);
+#ifdef __LP64__
+			db_printf(" (threaded)                  %s\n",
+			    p->p_comm);
+#else
+			db_printf(" (threaded)          %s\n", p->p_comm);
+#endif
 		FOREACH_THREAD_IN_PROC(p, td) {
-			dumpthread(p, td);
-			if (quit)
+			dumpthread(p, td, p->p_flag & P_HADTHREADS);
+			if (db_pager_quit)
 				break;
 		}
-		/* PROC_UNLOCK(p); */
 
 		p = LIST_NEXT(p, p_list);
 		if (p == NULL && np > 0)
 			p = LIST_FIRST(&zombproc);
     	}
-	/* sx_sunlock(&allproc_lock); */
 }
 
 static void
-dumpthread(volatile struct proc *p, volatile struct thread *td)
+dumpthread(volatile struct proc *p, volatile struct thread *td, int all)
+{
+	char state[9], wprefix;
+	const char *wmesg;
+	void *wchan;
+	
+	if (all) {
+		db_printf("%6d                  ", td->td_tid);
+		switch (td->td_state) {
+		case TDS_RUNNING:
+			snprintf(state, sizeof(state), "Run");
+			break;
+		case TDS_RUNQ:
+			snprintf(state, sizeof(state), "RunQ");
+			break;
+		case TDS_CAN_RUN:
+			snprintf(state, sizeof(state), "CanRun");
+			break;
+		case TDS_INACTIVE:
+			snprintf(state, sizeof(state), "Inactv");
+			break;
+		case TDS_INHIBITED:
+			state[0] = '\0';
+			if (TD_ON_LOCK(td))
+				strlcat(state, "L", sizeof(state));
+			if (TD_IS_SLEEPING(td)) {
+				if (td->td_flags & TDF_SINTR)
+					strlcat(state, "S", sizeof(state));
+				else
+					strlcat(state, "D", sizeof(state));
+			}
+			if (TD_IS_SWAPPED(td))
+				strlcat(state, "W", sizeof(state));
+			if (TD_AWAITING_INTR(td))
+				strlcat(state, "I", sizeof(state));
+			if (TD_IS_SUSPENDED(td))
+				strlcat(state, "s", sizeof(state));
+			if (state[0] != '\0')
+				break;
+		default:
+			snprintf(state, sizeof(state), "???");
+		}			
+		db_printf(" %-6.6s ", state);
+	}
+	wprefix = ' ';
+	if (TD_ON_LOCK(td)) {
+		wprefix = '*';
+		wmesg = td->td_lockname;
+		wchan = td->td_blocked;
+	} else if (TD_ON_SLEEPQ(td)) {
+		wmesg = td->td_wmesg;
+		wchan = td->td_wchan;
+	} else if (TD_IS_RUNNING(td)) {
+		snprintf(state, sizeof(state), "CPU %d", td->td_oncpu);
+		wmesg = state;
+		wchan = NULL;
+	} else {
+		wmesg = "";
+		wchan = NULL;
+	}
+	db_printf("%c%-8.8s ", wprefix, wmesg);
+	if (wchan == NULL)
+#ifdef __LP64__
+		db_printf("%18s ", "");
+#else
+		db_printf("%10s ", "");
+#endif
+	else
+		db_printf("%p ", wchan);
+	if (p->p_flag & P_SYSTEM)
+		db_printf("[");
+	if (td->td_name[0] != '\0')
+		db_printf("%s", td->td_name);
+	else
+		db_printf("%s", td->td_proc->p_comm);
+	if (p->p_flag & P_SYSTEM)
+		db_printf("]");
+	db_printf("\n");
+}
+
+DB_SHOW_COMMAND(thread, db_show_thread)
 {
+	struct thread *td;
+	boolean_t comma;
 
-	if (p->p_flag & P_HADTHREADS)
-		db_printf( "   thread %p ksegrp %p ", td, td->td_ksegrp);
-	if (TD_ON_SLEEPQ(td))
-		db_printf("[SLPQ %s %p]", td->td_wmesg, (void *)td->td_wchan);
+	/* Determine which thread to examine. */
+	if (have_addr)
+		td = db_lookup_thread(addr, FALSE);
+	else
+		td = kdb_thread;
+
+	db_printf("Thread %d at %p:\n", td->td_tid, td);
+	db_printf(" proc (pid %d): %p\n", td->td_proc->p_pid, td->td_proc);
+	if (td->td_name[0] != '\0')
+		db_printf(" name: %s\n", td->td_name);
+	db_printf(" flags: %#x ", td->td_flags);
+	db_printf(" pflags: %#x\n", td->td_pflags);
+	db_printf(" state: ");
 	switch (td->td_state) {
+	case TDS_INACTIVE:
+		db_printf("INACTIVE\n");
+		break;
+	case TDS_CAN_RUN:
+		db_printf("CAN RUN\n");
+		break;
+	case TDS_RUNQ:
+		db_printf("RUNQ\n");
+		break;
+	case TDS_RUNNING:
+		db_printf("RUNNING (CPU %d)\n", td->td_oncpu);
+		break;
 	case TDS_INHIBITED:
-		if (TD_ON_LOCK(td)) {
-			db_printf("[LOCK %6s %8p]",
-			    td->td_lockname,
-			    (void *)td->td_blocked);
-		}
+		db_printf("INHIBITED: {");
+		comma = FALSE;
 		if (TD_IS_SLEEPING(td)) {
-			db_printf("[SLP]");
-		}  
-		if (TD_IS_SWAPPED(td)) {
-			db_printf("[SWAP]");
+			db_printf("SLEEPING");
+			comma = TRUE;
 		}
 		if (TD_IS_SUSPENDED(td)) {
-			db_printf("[SUSP]");
+			if (comma)
+				db_printf(", ");
+			db_printf("SUSPENDED");
+			comma = TRUE;
+		}
+		if (TD_IS_SWAPPED(td)) {
+			if (comma)
+				db_printf(", ");
+			db_printf("SWAPPED");
+			comma = TRUE;
+		}
+		if (TD_ON_LOCK(td)) {
+			if (comma)
+				db_printf(", ");
+			db_printf("LOCK");
+			comma = TRUE;
 		}
 		if (TD_AWAITING_INTR(td)) {
-			db_printf("[IWAIT]");
+			if (comma)
+				db_printf(", ");
+			db_printf("IWAIT");
 		}
+		db_printf("}\n");
 		break;
-	case TDS_CAN_RUN:
-		db_printf("[Can run]");
+	default:
+		db_printf("??? (%#x)\n", td->td_state);
 		break;
-	case TDS_RUNQ:
-		db_printf("[RUNQ]");
+	}
+	if (TD_ON_LOCK(td))
+		db_printf(" lock: %s  turnstile: %p\n", td->td_lockname,
+		    td->td_blocked);
+	if (TD_ON_SLEEPQ(td))
+		db_printf(" wmesg: %s  wchan: %p\n", td->td_wmesg,
+		    td->td_wchan);
+	db_printf(" priority: %d\n", td->td_priority);
+}
+
+DB_SHOW_COMMAND(proc, db_show_proc)
+{
+	struct thread *td;
+	struct proc *p;
+	int i;
+
+	/* Determine which process to examine. */
+	if (have_addr)
+		p = db_lookup_proc(addr);
+	else
+		p = kdb_thread->td_proc;
+
+	db_printf("Process %d (%s) at %p:\n", p->p_pid, p->p_comm, p);
+	db_printf(" state: ");
+	switch (p->p_state) {
+	case PRS_NEW:
+		db_printf("NEW\n");
 		break;
-	case TDS_RUNNING:
-		db_printf("[CPU %d]", td->td_oncpu);
+	case PRS_NORMAL:
+		db_printf("NORMAL\n");
 		break;
-	case TDS_INACTIVE:
-		db_printf("[INACTIVE]");
+	case PRS_ZOMBIE:
+		db_printf("ZOMBIE\n");
 		break;
 	default:
-		db_printf("[UNK: %#x]", td->td_state);
+		db_printf("??? (%#x)\n", p->p_state);
 	}
-	if (p->p_flag & P_HADTHREADS) {
-#ifdef KEF_DIDRUN
-		if (td->td_kse)
-			db_printf("[kse %p]", td->td_kse);
-#endif
+	if (p->p_ucred != NULL) {
+		db_printf(" uid: %d  gids: ", p->p_ucred->cr_uid);
+		for (i = 0; i < p->p_ucred->cr_ngroups; i++) {
+			db_printf("%d", p->p_ucred->cr_groups[i]);
+			if (i < (p->p_ucred->cr_ngroups - 1))
+				db_printf(", ");
+		}
 		db_printf("\n");
-	} else
-		db_printf(" %s\n", p->p_comm);
+	}
+	if (p->p_pptr != NULL)
+		db_printf(" parent: pid %d at %p\n", p->p_pptr->p_pid,
+		    p->p_pptr);
+	if (p->p_leader != NULL && p->p_leader != p)
+		db_printf(" leader: pid %d at %p\n", p->p_leader->p_pid,
+		    p->p_leader);
+	if (p->p_sysent != NULL)
+		db_printf(" ABI: %s\n", p->p_sysent->sv_name);
+	if (p->p_args != NULL)
+		db_printf(" arguments: %.*s\n", (int)p->p_args->ar_length,
+		    p->p_args->ar_args);
+	db_printf(" threads: %d\n", p->p_numthreads);
+	FOREACH_THREAD_IN_PROC(p, td) {
+		dumpthread(p, td, 1);
+		if (db_pager_quit)
+			break;
+	}
 }


More information about the Midnightbsd-cvs mailing list