Subject: Re: ddb help command patch
To: Martin Husemann <martin@duskware.de>
From: Adam Hamsik <haaaad@gmail.com>
List: tech-kern
Date: 06/26/2007 17:48:32
--Apple-Mail-20-554765863
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	delsp=yes;
	format=flowed


On Jun 8, 2007, at 12:56 AM, Martin Husemann wrote:

> On Fri, Jun 08, 2007 at 12:19:59AM +0200, Adam Hamsik wrote:
>> db>help break
>>
>> prints "Set breakpoint to address"
>
> I like the general idea, but I would like to make the additional help
> support optional. This has two reasons:
>
>  - ddb is very usefull even in tiny configurations where every kernel
>    byte counts
>  - people doing heavy kernel work might decide to not need the help
>    a lot (or have the other machine, where they cross build from,
>    easily available to run "man ddb")
>
> Could you define a macro to declare the DDB command and make it  
> just ignore
> the help string parameter if compiled w/o the DDB_VERBOSE_HELP (or  
> whatever
> we'd call it) option?
>
> i.e. change this
>
>        { "mbuf", "Show number and status of mbuf's.",   
> db_mbuf_print_cmd,
> 	0,      NULL },
>
> to:
>
> 	DDB_DECLARE_SIMPLE_CMD("mbuf", "Show number and status of mbuf's.",
> 	    db_mbuf_print_cmd)
>
> (and a non-SIMPLE variant if the "flags" or "more" field are filled  
> in?)
>
>
> And feel free to use other names, I'm not good at inventing them ;-}
>
> Martin
Hi

I have written another patch which improve my last patch little bit.  
I have added to entries to
struct db_command {
  char *cmd_arg;
  char *cmd_descr;
};

and I defined new macro DDB_ADD_CMD. DDB_ADD_CMD if option  
DDB_VERBOSE_HELP is defined adds description and argument message. If  
DDB_VERBOSE_HELP is not defined DDB_ADD_CMD will add only NULL for  
them (for every entry 2 x char*).

In this structure I store all help infos. I have declared kernel  
option DDB_VERBOSE_HELP ,too.


Before I fully implement this patch I want to ask some questions.
I have to convert all other architectures for now only i386 is  
converted.

1) ddb(4) is incomplete in our man page we don't have any info about
    callout
    show aio_jobs
    show lock
    show malloc
    show mbuf
  Can somebody send me info's about these functions and I will add  
them to our
  ddb(4) and to the my patch.

2) I think about dynamic ddb command/help API which could be used for  
registering/unregistering ddb commands. Now all ddb commands are  
stored in static array db_command_table. Problem is that if every  
kernel component want to add some ddb_commands kernel programer have  
to add entry to the ddb_command_table. If we use dynamic structure  
like linked list we can add/remove commands in realtime.

API:

int
db_reg_command(struct cmd_list *cmd_list, struct cmd_list **cmd_command,
char *cmd_name,*cmd_func);

db_reg_help(*cmd_command,char* descr, char** cmd_func_arg);

db_unreg_command(*cmd_list, char* cmd_name);

struct cmd_list*
db_search_command(struct cmd_list*, char* cmd_name);

/*this function will create default list of commands*/
db_init(struct cmd_list**);

(db_get_help,db_get_func,db_get_cmd) ??

Pro:

LKM and other parts of kernel can register/unregister ddb commands in  
easy way.

more useable ddb.


Cons:
I have to initialize this list when ddb is run.(lot of malloc's for  
every added command 2 one for command structure and second for help 
(not needed))


Regards
-----------------------------------------
Adam Hamsik
jabber: haad@jabber.org
icq: 249727910

Proud NetBSD user.

We program to have fun.
Even when we program for money, we want to have fun as well.
~ Yukihiro Matsumoto


--Apple-Mail-20-554765863
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name=ddb_help_2.diff
Content-Disposition: attachment;
	filename=ddb_help_2.diff

Index: db_command.c
===================================================================
RCS file: /cvsroot/src/sys/ddb/db_command.c,v
retrieving revision 1.96
diff -u -r1.96 db_command.c
--- db_command.c	30 Apr 2007 14:44:30 -0000	1.96
+++ db_command.c	26 Jun 2007 15:46:58 -0000
@@ -83,7 +83,23 @@
 #define	CMD_FOUND	1
 #define	CMD_NONE	2
 #define	CMD_AMBIGUOUS	3
-#define	CMD_HELP	4
+
+#define CMD_SWITCH(result) do {          \
+        switch (result) {                \
+        case CMD_NONE:                   \
+		 db_printf("No such command\n"); \
+		 db_flush_lex();                 \
+		 return;                         \
+        case CMD_AMBIGUOUS:              \
+		 db_printf("Ambiguous\n");       \
+		 db_flush_lex();                 \
+		 return;                         \
+        default:                         \
+		 break;                          \
+        }                                \
+        } while(0)
+
+
 
 /*
  * Exported global variables
@@ -103,6 +119,7 @@
 static bool	 db_ed_style = true;
 
 static void	db_buf_print_cmd(db_expr_t, bool, db_expr_t, const char *);
+
 static void	db_cmd_list(const struct db_command *);
 static int	db_cmd_search(const char *, const struct db_command *,
 		    const struct db_command **);
@@ -110,6 +127,10 @@
 		    const struct db_command *);
 static void	db_event_print_cmd(db_expr_t, bool, db_expr_t, const char *);
 static void	db_fncall(db_expr_t, bool, db_expr_t, const char *);
+static void db_help_print_cmd(db_expr_t, bool, db_expr_t, const char *);
+static void	db_lock_print_cmd(db_expr_t, bool, db_expr_t, const char *);
+static void	db_mount_print_cmd(db_expr_t, bool, db_expr_t, const char *);
+static void	db_mbuf_print_cmd(db_expr_t, bool, db_expr_t, const char *);
 static void	db_malloc_print_cmd(db_expr_t, bool, db_expr_t, const char *);
 static void	db_map_print_cmd(db_expr_t, bool, db_expr_t, const char *);
 static void	db_namecache_print_cmd(db_expr_t, bool, db_expr_t, const char *);
@@ -123,46 +144,64 @@
 static void	db_sync_cmd(db_expr_t, bool, db_expr_t, const char *);
 static void	db_uvmexp_print_cmd(db_expr_t, bool, db_expr_t, const char *);
 static void	db_vnode_print_cmd(db_expr_t, bool, db_expr_t, const char *);
-static void	db_lock_print_cmd(db_expr_t, bool, db_expr_t, const char *);
-static void	db_mount_print_cmd(db_expr_t, bool, db_expr_t, const char *);
-static void	db_mbuf_print_cmd(db_expr_t, bool, db_expr_t, const char *);
+
 
 /*
  * 'show' commands
  */
-
+#if defined(DDB_VERBOSE_HELP)
+#define DDB_ADD_CMD(name,funct,type,cmd_descr,cmd_arg,more)\
+ name,funct,type,cmd_descr,cmd_arg,more
+#else
+#define DDB_ADD_CMD(name,funct,type,cmd_descr,cmd_arg,more)\
+ name,funct,type,NULL,NULL,more
+#endif
+   
 static const struct db_command db_show_all_cmds[] = {
-	{ "callout",	db_show_callout,	0, NULL },
-	{ "pages",	db_show_all_pages,	0, NULL },
-	{ "procs",	db_show_all_procs,	0, NULL },
-	{ "pools",	db_show_all_pools,	0, NULL },
-	{ NULL, 	NULL, 			0, NULL }
+  { DDB_ADD_CMD("callout",db_show_callout,	    0,NULL,NULL,NULL) },
+  { DDB_ADD_CMD("pages",	db_show_all_pages,	0,NULL,NULL,NULL) },
+  { DDB_ADD_CMD("procs",	db_show_all_procs,	0,NULL,NULL,NULL) },
+  { DDB_ADD_CMD("pools",	db_show_all_pools,	0,NULL,NULL,NULL) },
+  { DDB_ADD_CMD(NULL, 	NULL, 			0, NULL,NULL,NULL )}
 };
 
 static const struct db_command db_show_cmds[] = {
-	{ "aio_jobs",	db_show_aio_jobs,	0,	NULL },
-	{ "all",	NULL,			0,	db_show_all_cmds },
+  { DDB_ADD_CMD("aio_jobs",	db_show_aio_jobs,	0,"Show aio jobs", NULL,	NULL) },
+  { DDB_ADD_CMD("all",	NULL,			0,NULL,NULL, db_show_all_cmds )},
 #if defined(INET) && (NARP > 0)
-	{ "arptab",	db_show_arptab,		0,	NULL },
+  { DDB_ADD_CMD("arptab",	db_show_arptab,		0,NULL,NULL,	NULL) },
 #endif
-	{ "breaks",	db_listbreak_cmd, 	0,	NULL },
-	{ "buf",	db_buf_print_cmd,	0,	NULL },
-	{ "event",	db_event_print_cmd,	0,	NULL },
-	{ "lock",	db_lock_print_cmd,	0,	NULL },
-	{ "malloc",	db_malloc_print_cmd,	0,	NULL },
-	{ "map",	db_map_print_cmd,	0,	NULL },
-	{ "mount",	db_mount_print_cmd,	0,	NULL },
-	{ "mbuf",	db_mbuf_print_cmd,	0,	NULL },
-	{ "ncache",	db_namecache_print_cmd,	0,	NULL },
-	{ "object",	db_object_print_cmd,	0,	NULL },
-	{ "page",	db_page_print_cmd,	0,	NULL },
-	{ "pool",	db_pool_print_cmd,	0,	NULL },
-	{ "registers",	db_show_regs,		0,	NULL },
-	{ "sched_qs",	db_show_sched_qs,	0,	NULL },
-	{ "uvmexp",	db_uvmexp_print_cmd,	0,	NULL },
-	{ "vnode",	db_vnode_print_cmd,	0,	NULL },
-	{ "watches",	db_listwatch_cmd, 	0,	NULL },
-	{ NULL,		NULL,			0,	NULL }
+  { DDB_ADD_CMD("breaks",	db_listbreak_cmd, 	0,"Display all breaks.", NULL,	NULL) },
+  { DDB_ADD_CMD("buf",	db_buf_print_cmd,	0,
+				"Print the struct buf at address.", "[/f] address",	NULL) },
+  { DDB_ADD_CMD("event",	db_event_print_cmd,	0,
+				"Print all the non-zero evcnt(9) event counters.", "[/f]",	NULL) },
+  { DDB_ADD_CMD("lock",	db_lock_print_cmd,	0,NULL,NULL,NULL) },
+  { DDB_ADD_CMD("malloc",	db_malloc_print_cmd,0,NULL,NULL,NULL) },
+  { DDB_ADD_CMD("map",	db_map_print_cmd,	0,
+				"Print the vm_map at address.", "[/f] address",	NULL) },
+  { DDB_ADD_CMD("mount",	db_mount_print_cmd,	0,
+				"Print the mount structure at address.", "[/f] address",	NULL) },
+  { DDB_ADD_CMD("mbuf",	db_mbuf_print_cmd,	0,NULL,NULL, NULL) },
+  { DDB_ADD_CMD("ncache",	db_namecache_print_cmd,	0,
+				"Dump the namecache list.", "address", 	NULL) },
+  { DDB_ADD_CMD("object",	db_object_print_cmd,	0,
+				"Print the vm_object at address.", "[/f] address",	NULL) },
+  { DDB_ADD_CMD("page",	db_page_print_cmd,	0,
+				"Print the vm_page at address.", "[/f] address",	NULL) },
+  { DDB_ADD_CMD("pool",	db_pool_print_cmd,	0,
+				"Print the pool at address.", "[/clp] address",	NULL) },
+  { DDB_ADD_CMD("registers",	db_show_regs,		0,
+				"Display the register set.", "[/u]",	NULL) },
+  { DDB_ADD_CMD("sched_qs",	db_show_sched_qs,	0,
+				"Print the state of the scheduler's run queues.",NULL, NULL) },
+  { DDB_ADD_CMD("uvmexp",	db_uvmexp_print_cmd, 0,
+				"Print a selection of UVM counters and statistics.", NULL, 	NULL) },
+  { DDB_ADD_CMD("vnode",	db_vnode_print_cmd,	0,
+				"Print the vnode at address.", "[/f] address",	NULL) },
+  { DDB_ADD_CMD("watches",	db_listwatch_cmd, 	0,
+				"Display all watchpoints.", NULL,	NULL) },
+  { DDB_ADD_CMD(NULL,		NULL,			0,NULL,NULL,	NULL )}
 };
 
 /* arch/<arch>/<arch>/db_interface.c */
@@ -171,45 +210,82 @@
 #endif
 
 static const struct db_command db_command_table[] = {
-	{ "b",		db_breakpoint_cmd,	0,		NULL },
-	{ "break",	db_breakpoint_cmd,	0,		NULL },
-	{ "bt",		db_stack_trace_cmd,	0,		NULL },
-	{ "c",		db_continue_cmd,	0,		NULL },
-	{ "call",	db_fncall,		CS_OWN,		NULL },
-	{ "callout",	db_show_callout,	0,		NULL },
-	{ "continue",	db_continue_cmd,	0,		NULL },
-	{ "d",		db_delete_cmd,		0,		NULL },
-	{ "delete",	db_delete_cmd,		0,		NULL },
-	{ "dmesg",	db_dmesg,		0,		NULL },
-	{ "dwatch",	db_deletewatch_cmd,	0,		NULL },
-	{ "examine",	db_examine_cmd,		CS_SET_DOT, 	NULL },
-	{ "kill",	db_kill_proc,		CS_OWN,		NULL },
+  { DDB_ADD_CMD("b",		db_breakpoint_cmd,	0,
+				"Set a breakpoint at address", "[/u] address[,count].", NULL) },
+  { DDB_ADD_CMD("break",	db_breakpoint_cmd,	0,
+				"Set a breakpoint at address", "[/u] address[,count].", NULL) },
+  { DDB_ADD_CMD("bt",		db_stack_trace_cmd,	0,
+				"Show backtrace.", "See help trace.", NULL) },
+  { DDB_ADD_CMD("c",		db_continue_cmd,	0,"Continue execution.", "[/c]", NULL) },
+  { DDB_ADD_CMD("call",	db_fncall,		CS_OWN,
+				"Call the function", "address[(expression[,...])]", NULL) },
+  { DDB_ADD_CMD("callout",	db_show_callout,	0, NULL, NULL, NULL) },
+  { DDB_ADD_CMD("continue",	db_continue_cmd,	0,"Continue execution.", "[/c]", NULL) },
+  { DDB_ADD_CMD("d",		db_delete_cmd,		0,
+				"Delete a breakpoint.", "address | #number",		NULL) },
+  { DDB_ADD_CMD("delete",	db_delete_cmd,		0,
+				"Delete a breakpoint.", "address | #number",		NULL) },
+  { DDB_ADD_CMD("dmesg",	db_dmesg,		0,
+				"Show kernel message buffer.", "[count]",	NULL) },
+  { DDB_ADD_CMD("dwatch",	db_deletewatch_cmd,	0,
+				"Delete the watchpoint.", "address",		NULL) },
+  { DDB_ADD_CMD("examine",	db_examine_cmd,		CS_SET_DOT,
+				"Display the address locations.",
+				"[/modifier] address[,count]", 	NULL) },
+  { DDB_ADD_CMD("help",   db_help_print_cmd, CS_OWN,"Display help about commands",
+				"Use other commands as arguments.",  NULL) },
+  { DDB_ADD_CMD("kill",	db_kill_proc,		CS_OWN,
+				"Send a signal to the process","pid[,signal_number]",		NULL) },
 #ifdef KGDB
-	{ "kgdb",	db_kgdb_cmd,		0,		NULL },
+  { DDB_ADD_CMD("kgdb",	db_kgdb_cmd,		0,		NULL) },
 #endif
 #ifdef DB_MACHINE_COMMANDS
-	{ "machine",	NULL,			0, db_machine_command_table },
+  { DDB_ADD_CMD("machine",	NULL,			0, NULL,NULL,db_machine_command_table) },
 #endif
-	{ "match",	db_trace_until_matching_cmd,0,		NULL },
-	{ "next",	db_trace_until_matching_cmd,0,		NULL },
-	{ "p",		db_print_cmd,		0,		NULL },
-	{ "print",	db_print_cmd,		0,		NULL },
-	{ "ps",		db_show_all_procs,	0,		NULL },
-	{ "reboot",	db_reboot_cmd,		CS_OWN,		NULL },
-	{ "s",		db_single_step_cmd,	0,		NULL },
-	{ "search",	db_search_cmd,		CS_OWN|CS_SET_DOT, NULL },
-	{ "set",	db_set_cmd,		CS_OWN,		NULL },
-	{ "show",	NULL,			0,		db_show_cmds },
-	{ "sifting",	db_sifting_cmd,		CS_OWN,		NULL },
-	{ "step",	db_single_step_cmd,	0,		NULL },
-	{ "sync",	db_sync_cmd,		CS_OWN,		NULL },
-	{ "trace",	db_stack_trace_cmd,	0,		NULL },
-	{ "until",	db_trace_until_call_cmd,0,		NULL },
-	{ "w",		db_write_cmd,		CS_MORE|CS_SET_DOT, NULL },
-	{ "watch",	db_watchpoint_cmd,	CS_MORE,	NULL },
-	{ "write",	db_write_cmd,		CS_MORE|CS_SET_DOT, NULL },
-	{ "x",		db_examine_cmd,		CS_SET_DOT, 	NULL },
-	{ NULL, 	NULL,			0,		NULL }
+  { DDB_ADD_CMD("match",	db_trace_until_matching_cmd,0,
+				"Stop at the matching return instruction.","See help next",		NULL) },
+  { DDB_ADD_CMD("next",	db_trace_until_matching_cmd,0,
+				"Stop at the matching return instruction.","[/p]",		NULL) },
+  { DDB_ADD_CMD("p",		db_print_cmd,		0,
+				"Print address according to the format.",
+				"[/axzodurc] address [address ...]",		NULL) },
+  { DDB_ADD_CMD("print",	db_print_cmd,		0,
+				"Print address according to the format.",
+				"[/axzodurc] address [address ...]",		NULL) },
+  { DDB_ADD_CMD("ps",		db_show_all_procs,	0,
+				"Print all processes.","See show all procs",		NULL) },
+  { DDB_ADD_CMD("reboot",	db_reboot_cmd,		CS_OWN,
+				"Reboot","0x1  RB_ASKNAME, 0x2 RB_SINGLE, 0x4 RB_NOSYNC, 0x8 RB_HALT,"
+				"0x40 RB_KDB, 0x100 RB_DUMP, 0x808 RB_POWERDOWN",NULL) },
+  { DDB_ADD_CMD("s",		db_single_step_cmd,	0,
+				"Single-step count times.","[/p] [,count]",		NULL) },
+  { DDB_ADD_CMD("search",	db_search_cmd,		CS_OWN|CS_SET_DOT,
+				"Search memory from address for value.",
+				"[/bhl] address value [mask] [,count]", NULL) },
+  { DDB_ADD_CMD("set",	db_set_cmd,		CS_OWN,
+				"Set the named variable","$variable [=] expression", NULL) },
+  { DDB_ADD_CMD("show",	NULL,			0,"Show kernel stats.", NULL, db_show_cmds)},
+  { DDB_ADD_CMD("sifting",	db_sifting_cmd,		CS_OWN,
+				"Search the symbol tables ","[/F] string", NULL) },
+  { DDB_ADD_CMD("step",	db_single_step_cmd,	0,
+				"Single-step count times.","[/p] [,count]",	NULL) },
+  { DDB_ADD_CMD("sync",	db_sync_cmd,		CS_OWN,
+				"Force a crash dump, and then reboot.",NULL,		NULL) },
+  { DDB_ADD_CMD("trace",	db_stack_trace_cmd,	0,
+				"Stack trace from frame-address.",
+				"[/u[l]] [frame-address][,count]", NULL) },
+  { DDB_ADD_CMD("until",	db_trace_until_call_cmd,0,
+				"Stop at the next call or return instruction.","[/p]", NULL) },
+  { DDB_ADD_CMD("w",		db_write_cmd,		CS_MORE|CS_SET_DOT,
+				"Set a watchpoint for a region. ","address[,size]", NULL) },
+  { DDB_ADD_CMD("watch",	db_watchpoint_cmd,	CS_MORE,
+				"Set a watchpoint for a region. ","address[,size]",	NULL) },
+  { DDB_ADD_CMD("write",	db_write_cmd,		CS_MORE|CS_SET_DOT,
+				"Write the expressions at succeeding locations.",
+				"[/bhl] address expression [expression ...]", NULL) },
+  { DDB_ADD_CMD("x",		db_examine_cmd,		CS_SET_DOT,
+				"Display the address locations.", "[/modifier] address[,count]", NULL) },
+  { DDB_ADD_CMD(NULL, 	NULL,		   0, NULL, NULL,	 NULL )}
 };
 
 static const struct db_command	*db_last_command = NULL;
@@ -220,6 +296,9 @@
 #endif /* defined(DDB_COMMANDONENTER) */
 #define	DB_LINE_SEP	';'
 
+
+
+
 /*
  * Utility routine - discard tokens through end-of-line.
  */
@@ -227,7 +306,6 @@
 db_skip_to_eol(void)
 {
 	int t;
-
 	do {
 		t = db_read_token();
 	} while (t != tEOL);
@@ -342,18 +420,12 @@
 			}
 		}
 	}
-	if (result == CMD_NONE) {
-		/* check for 'help' */
-		if (name[0] == 'h' && name[1] == 'e'
-		    && name[2] == 'l' && name[3] == 'p')
-			result = CMD_HELP;
-	}
 	return (result);
 }
 
 static void
-db_cmd_list(const struct db_command *table)
-{
+db_cmd_list(const struct db_command *table){
+  
 	int	 i, j, w, columns, lines, width=0, numcmds;
 	const char	*p;
 
@@ -434,29 +506,14 @@
 		 */
 		while (cmd_table) {
 			result = db_cmd_search(db_tok_string, cmd_table, &cmd);
-			switch (result) {
-			case CMD_NONE:
-				db_printf("No such command\n");
-				db_flush_lex();
-				return;
-			case CMD_AMBIGUOUS:
-				db_printf("Ambiguous\n");
-				db_flush_lex();
-				return;
-			case CMD_HELP:
-				db_cmd_list(cmd_table);
-				db_flush_lex();
-				return;
-			default:
-				break;
-			}
+			CMD_SWITCH(result);
 			if ((cmd_table = cmd->more) != 0) {
 				t = db_read_token();
-				if (t != tIDENT) {
+/*				if (t != tIDENT) {
 					db_cmd_list(cmd_table);
 					db_flush_lex();
 					return;
-				}
+					}*/
 			}
 		}
 
@@ -529,6 +586,55 @@
 		}
 	}
 }
+static void
+db_help_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
+				  const char *modif){
+
+  const struct db_command *help;
+
+  int t,result;
+
+  t=db_read_token();
+  if (t == tIDENT){
+	result = db_cmd_search(db_tok_string, db_command_table, &help);
+
+	CMD_SWITCH(result);
+
+	if (help->cmd_descr != NULL)
+	  db_printf("Command: %s Arguments: %s\n Descr: %s\n",
+				help->name,help->cmd_arg,help->cmd_descr);
+	else
+	  db_printf("Command: %s Doesn't have any help message included.\n",
+				help->name);
+
+	while (help->more != NULL){
+
+	  t=db_read_token();
+
+	  if (t == tIDENT){
+		result = db_cmd_search(db_tok_string, help->more, &help);
+		
+		CMD_SWITCH(result);
+		
+		if (help->cmd_arg != NULL)
+		  db_printf("Command: %s Arguments: %s\n Descr: %s\n",
+					help->name,help->cmd_arg,help->cmd_descr);
+		else
+		  db_printf("Command: %s Doesn't have any help message included.\n",
+					help->name);
+	  } else {
+		db_printf("%s subcommands:\n",help->name);
+		db_cmd_list(help->more);
+		break;
+	  }
+	}
+  } else {
+		  db_cmd_list(db_command_table);
+		  db_flush_lex();
+  }
+
+	return;
+}
 
 /*ARGSUSED*/
 static void
Index: db_command.h
===================================================================
RCS file: /cvsroot/src/sys/ddb/db_command.h,v
retrieving revision 1.27
diff -u -r1.27 db_command.h
--- db_command.h	22 Feb 2007 04:38:05 -0000	1.27
+++ db_command.h	26 Jun 2007 15:46:58 -0000
@@ -52,12 +52,17 @@
  */
 struct db_command {
 	const char	*name;		/* command name */
-	/* function to call */
+  
+  /* function to call */
 	void		(*fcn)(db_expr_t, bool, db_expr_t, const char *);
 	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 */
-	const struct db_command *more;	/* another level of command */
+
+  const char *cmd_descr; /*description of command*/
+  const char *cmd_arg;   /*command arguments*/
+
+  const struct db_command *more;	/* another level of command */
 };
Index: files.ddb
===================================================================
RCS file: /cvsroot/src/sys/ddb/files.ddb,v
retrieving revision 1.1
diff -u -r1.1 files.ddb
--- files.ddb	27 Nov 2005 22:44:35 -0000	1.1
+++ files.ddb	26 Jun 2007 15:46:58 -0000
@@ -3,10 +3,10 @@
 #
 # DDB options
 #
-defflag opt_ddb.h		DDB
+defflag opt_ddb.h		DDB 
 defparam opt_ddbparam.h		DDB_FROMCONSOLE DDB_ONPANIC DDB_HISTORY_SIZE
 				DDB_BREAK_CHAR DDB_KEYCODE SYMTAB_SPACE
-				DDB_COMMANDONENTER
+				DDB_COMMANDONENTER DDB_VERBOSE_HELP
 
 file	ddb/db_access.c			ddb | kgdb	# XXX kgdb reference
 file	ddb/db_aout.c			ddb

--Apple-Mail-20-554765863
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	format=flowed




--Apple-Mail-20-554765863--