aboutsummaryrefslogtreecommitdiff
path: root/sys/ddb/ddb.h
diff options
context:
space:
mode:
authorSam Leffler <sam@FreeBSD.org>2008-09-15 22:45:14 +0000
committerSam Leffler <sam@FreeBSD.org>2008-09-15 22:45:14 +0000
commit39297ba45528361278dc0522b99c659f3a38cbb8 (patch)
tree6a6cd52918de6f264f6071e5f55fc410c7f1633d /sys/ddb/ddb.h
parentca3d37955c7c41e64a80c97b3f1c1fa4e9ff4897 (diff)
downloadsrc-39297ba45528361278dc0522b99c659f3a38cbb8.tar.gz
src-39297ba45528361278dc0522b99c659f3a38cbb8.zip
Make ddb command registration dynamic so modules can extend
the command set (only so long as the module is present): o add db_command_register and db_command_unregister to add and remove commands, respectively o replace linker sets with SYSINIT's (and SYSUINIT's) that register commands o expose 3 list heads: db_cmd_table, db_show_table, and db_show_all_table for registering top-level commands, show operands, and show all operands, respectively While here also: o sort command lists o add DB_ALIAS, DB_SHOW_ALIAS, and DB_SHOW_ALL_ALIAS to add aliases for existing commands o add "show all trace" as an alias for "show alltrace" o add "show all locks" as an alias for "show alllocks" Submitted by: Guillaume Ballet <gballet@gmail.com> (original version) Reviewed by: jhb MFC after: 1 month
Notes
Notes: svn path=/head/; revision=183054
Diffstat (limited to 'sys/ddb/ddb.h')
-rw-r--r--sys/ddb/ddb.h136
1 files changed, 90 insertions, 46 deletions
diff --git a/sys/ddb/ddb.h b/sys/ddb/ddb.h
index 57c5fd15985c..1afdfa39a54e 100644
--- a/sys/ddb/ddb.h
+++ b/sys/ddb/ddb.h
@@ -43,6 +43,9 @@ SYSCTL_DECL(_debug_ddb);
#include <machine/db_machdep.h> /* type definitions */
+#include <sys/queue.h> /* LIST_* */
+#include <sys/kernel.h> /* SYSINIT */
+
#ifndef DB_MAXARGS
#define DB_MAXARGS 10
#endif
@@ -73,36 +76,97 @@ SYSCTL_DECL(_debug_ddb);
int DB_CALL(db_expr_t, db_expr_t *, int, db_expr_t[]);
#endif
+/*
+ * There are three "command tables":
+ * - One for simple commands; a list of these is displayed
+ * by typing 'help' at the debugger prompt.
+ * - One for sub-commands of 'show'; to see this type 'show'
+ * without any arguments.
+ * - The last one for sub-commands of 'show all'; type 'show all'
+ * without any argument to get a list.
+ */
+struct command;
+LIST_HEAD(command_table, command);
+extern struct command_table db_cmd_table;
+extern struct command_table db_show_table;
+extern struct command_table db_show_all_table;
+
+/*
+ * Type signature for a function implementing a ddb command.
+ */
typedef void db_cmdfcn_t(db_expr_t addr, boolean_t have_addr, db_expr_t count,
char *modif);
-#define DB_COMMAND(cmd_name, func_name) \
- DB_FUNC(cmd_name, func_name, db_cmd_set, 0, NULL)
-#define DB_SHOW_COMMAND(cmd_name, func_name) \
- DB_FUNC(cmd_name, func_name, db_show_cmd_set, 0, NULL)
-#define DB_SHOW_ALL_COMMAND(cmd_name, func_name) \
- DB_FUNC(cmd_name, func_name, db_show_all_cmd_set, 0, NULL)
-
-#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 \
+/*
+ * Command table entry.
+ */
+struct command {
+ char * name; /* command name */
+ db_cmdfcn_t *fcn; /* function to call */
+ int flag; /* extra info: */
+#define CS_OWN 0x1 /* non-standard syntax */
+#define CS_MORE 0x2 /* standard syntax, but may have other words
+ * at end */
+#define CS_SET_DOT 0x100 /* set dot after command */
+ struct command_table *more; /* another level of command */
+ LIST_ENTRY(command) next; /* next entry in the command table */
+};
+
+/*
+ * Arrange for the specified ddb command to be defined and
+ * bound to the specified function. Commands can be defined
+ * in modules in which case they will be available only when
+ * the module is loaded.
+ */
+#define _DB_SET(_suffix, _name, _func, list, _flag, _more) \
+static struct command __CONCAT(_name,_suffix) = { \
+ .name = __STRING(_name), \
+ .fcn = _func, \
+ .flag = _flag, \
+ .more = _more \
}; \
-TEXT_SET(set, __CONCAT(cmd_name,_cmd))
+static void __CONCAT(__CONCAT(_name,_suffix),_add)(void *arg __unused) \
+ { db_command_register(&list, &__CONCAT(_name,_suffix)); } \
+SYSINIT(__CONCAT(_name,_suffix), SI_SUB_KLD, SI_ORDER_ANY, \
+ __CONCAT(__CONCAT(_name,_suffix),_add), NULL); \
+static void __CONCAT(__CONCAT(_name,_suffix),_del)(void *arg __unused) \
+ { db_command_unregister(&list, &__CONCAT(_name,_suffix)); } \
+SYSUNINIT(__CONCAT(_name,_suffix), SI_SUB_KLD, SI_ORDER_ANY, \
+ __CONCAT(__CONCAT(_name,_suffix),_del), NULL);
-#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); \
- \
+/*
+ * Like _DB_SET but also create the function declaration which
+ * must be followed immediately by the body; e.g.
+ * _DB_FUNC(_cmd, panic, db_panic, db_cmd_table, 0, NULL)
+ * {
+ * ...panic implementation...
+ * }
+ *
+ * This macro is mostly used to define commands placed in one of
+ * the ddb command tables; see DB_COMMAND, etc. below.
+ */
+#define _DB_FUNC(_suffix, _name, _func, list, _flag, _more) \
+static db_cmdfcn_t _func; \
+_DB_SET(_suffix, _name, _func, list, _flag, _more); \
static void \
-func_name(addr, have_addr, count, modif) \
- db_expr_t addr; \
- boolean_t have_addr; \
- db_expr_t count; \
- char *modif;
+_func(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif)
+
+/* common idom provided for backwards compatibility */
+#define DB_FUNC(_name, _func, list, _flag, _more) \
+ _DB_FUNC(_cmd, _name, _func, list, _flag, _more)
+
+#define DB_COMMAND(cmd_name, func_name) \
+ _DB_FUNC(_cmd, cmd_name, func_name, db_cmd_table, 0, NULL)
+#define DB_ALIAS(alias_name, func_name) \
+ _DB_SET(_cmd, alias_name, func_name, db_cmd_table, 0, NULL)
+#define DB_SHOW_COMMAND(cmd_name, func_name) \
+ _DB_FUNC(_show, cmd_name, func_name, db_show_table, 0, NULL)
+#define DB_SHOW_ALIAS(alias_name, func_name) \
+ _DB_SET(_show, alias_name, func_name, db_show_table, 0, NULL)
+#define DB_SHOW_ALL_COMMAND(cmd_name, func_name) \
+ _DB_FUNC(_show_all, cmd_name, func_name, db_show_all_table, 0, NULL)
+#define DB_SHOW_ALL_ALIAS(alias_name, func_name) \
+ _DB_SET(_show_all, alias_name, func_name, db_show_all_table, 0, NULL)
extern db_expr_t db_maxoff;
extern int db_indent;
@@ -150,6 +214,8 @@ void db_trace_self(void);
int db_trace_thread(struct thread *, int);
int db_value_of_name(const char *name, db_expr_t *valuep);
int db_write_bytes(vm_offset_t addr, size_t size, char *data);
+void db_command_register(struct command_table *, struct command *);
+void db_command_unregister(struct command_table *, struct command *);
db_cmdfcn_t db_breakpoint_cmd;
db_cmdfcn_t db_capture_cmd;
@@ -179,28 +245,6 @@ db_cmdfcn_t db_watchpoint_cmd;
db_cmdfcn_t db_write_cmd;
/*
- * 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 */
- int flag; /* extra info: */
-#define CS_OWN 0x1 /* non-standard syntax */
-#define CS_MORE 0x2 /* standard syntax, but may have other words
- * at end */
-#define CS_SET_DOT 0x100 /* set dot after command */
- struct command_table *more; /* another level of command */
-};
-
-/*
* Interface between DDB and the DDB output capture facility.
*/
struct dumperinfo;