Date: Mon, 18 Aug 2008 10:02:14 -0400 From: John Baldwin <jhb@freebsd.org> To: freebsd-hackers@freebsd.org Cc: Guillaume Ballet <gballet@gmail.com>, Sam Leffler <sam@freebsd.org> Subject: Re: Extending the ddb command set Message-ID: <200808181002.14885.jhb@freebsd.org> In-Reply-To: <fd183dc60808171017m7eabcef2xbe1845e54cda4c99@mail.gmail.com> References: <fd183dc60808160203r3d90c26dq4d282d2ef153d2db@mail.gmail.com> <48A70B37.60401@freebsd.org> <fd183dc60808171017m7eabcef2xbe1845e54cda4c99@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sunday 17 August 2008 01:17:54 pm Guillaume Ballet wrote: > On Sat, Aug 16, 2008 at 5:15 PM, Sam Leffler <sam@freebsd.org> wrote: > > Guillaume Ballet wrote: > >> Hello hackers, > >> > >> I am currently working on a small project and would like to add a few > >> commands to the set that is available in ddb. > >> > >> I found that very interesting albeit succinct presentation: > >> http://people.freebsd.org/~jhb/papers/bsdcan/2008/slides.odp<http://peop > >>le.freebsd.org/%7Ejhb/papers/bsdcan/2008/slides.odp> > >> > >> where the author hints that I should use DB_COMMAND, which I did. Yet > >> when invoking ddb, the command does not appear in the help list. I have > >> taken a look at the source code and was expecting set_db_cmd_set to > >> appear in my module's section list when calling objdump -h > >> > >> Is DB_COMMAND only working within the kernel itself, and not modules? > > > > That is correct; you can't add ddb cmds from modules. It should be > > doable; just hasn't been done yet. > > > > Sam > > It is indeed doable: Here are the diffs for a first attempt at doing > this. I am not entirely satisfied with it, though, as it does not work > with DB_SHOW_COMMAND and the likes... Also, I have to declare a lot of > ddb-related stuff into kern_linker.c and I don't like it. I am > currently working at improving the whole thing, but in the mean time > if someone wants to give it a try, comments/rants would be greatly > appreciated. A simpler approach is probably to make DB_COMMAND() use a SYSINIT to register new functions instead of teaching DDB about that linker set. You just need to write a shared "register_command()" function (and a deregister for SYSUNINIT for module unload) that the SYSINIT uses. This also probably requires changing the structure of the DDB tables, though you might be able to make it simpler now. You could probably just make the tables be sorted linked lists now instead of arrays. This would also remove the whole "aux table" hack. > Guillaume > > --- sys/linker.h.orig 2008-08-17 18:45:56.000000000 +0200 > +++ sys/linker.h 2008-08-17 18:50:57.000000000 +0200 > @@ -155,6 +155,9 @@ > int linker_ddb_search_symbol(caddr_t _value, c_linker_sym_t *_sym, > long *_diffp); > int linker_ddb_symbol_values(c_linker_sym_t _sym, linker_symval_t > *_symval); +struct command; > +int linker_ddb_cmd_search(char *, struct command **); > +int linker_ddb_cmd_list(void); > > > /* HWPMC helper */ > --- kern/kern_linker.c.orig 2008-08-17 08:38:51.000000000 +0200 > +++ kern/kern_linker.c 2008-08-17 18:47:45.000000000 +0200 > @@ -777,6 +777,9 @@ > * that the files list is inconsistant instead. > */ > > +#include <ddb/ddb.h> > +#include <ddb/db_output.h> > + > int > linker_ddb_lookup(const char *symstr, c_linker_sym_t *sym) > { > @@ -831,6 +834,52 @@ > } > return (ENOENT); > } > + > +int linker_ddb_cmd_list() > +{ > + linker_file_t lf; > + struct command **start, **stop, **search; > + > + TAILQ_FOREACH(lf, &linker_files, link) { > + if (!linker_file_lookup_set(lf,"db_cmd_set",&start,&stop,NULL)) { > + for (search=start; search < stop; search++) { > + db_printf("%-12s", (*search)->name); > + db_end_line(12); > + } > + } > + } > + > + return 0; > +} > + > +int linker_ddb_cmd_search(char *name, struct command **cmdp) > +{ > + linker_file_t lf; > + char *lp, *rp; > + struct command **cmd, **start, **stop; > + int c; > + > + TAILQ_FOREACH(lf, &linker_files, link) { > + if (!linker_file_lookup_set(lf, "db_cmd_set", &start, &stop, > NULL)) { + for (cmd=start; cmd < stop; cmd++) { > + lp = name; > + rp = (*cmd)->name; > + > + while((c = *lp) == *rp) { > + if (c == 0) { > + *cmdp = *cmd; > + return 0; > + } > + > + lp++; > + rp++; > + } > + } > + } > + } > + > + return -1; > +} > #endif > > /* > --- ddb/db_command.c.orig 2008-08-17 10:26:26.000000000 +0200 > +++ ddb/db_command.c 2008-08-17 18:42:22.000000000 +0200 > @@ -253,6 +253,9 @@ > if (result == CMD_UNIQUE) > return (CMD_UNIQUE); > } > + if (result == CMD_NONE && linker_ddb_cmd_search(name,cmdp) == 0) { > + result = CMD_UNIQUE; > + } > if (result == CMD_NONE) { > /* check for 'help' */ > if (name[0] == 'h' && name[1] == 'e' > @@ -280,6 +283,7 @@ > db_printf("%-12s", (*aux_cmdp)->name); > db_end_line(12); > } > + linker_ddb_cmd_list(); > } > > static void > --- ddb/db_command.h.orig 2008-08-17 18:37:34.000000000 +0200 > +++ ddb/db_command.h 2008-08-17 18:49:29.000000000 +0200 > @@ -46,4 +46,7 @@ > extern db_addr_t db_next; /* next address to be examined > or written */ > > +extern int linker_ddb_cmd_search(char*,struct command **); > +extern int linker_ddb_cmd_list(void); > + > #endif /* !_DDB_DB_COMMAND_H_ */ > _______________________________________________ > freebsd-hackers@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-hackers > To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org" -- John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200808181002.14885.jhb>