[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