diff options
author | Andy Fiddaman <omnios@citrus-it.co.uk> | 2018-10-23 13:54:51 +0000 |
---|---|---|
committer | Richard Lowe <richlowe@richlowe.net> | 2018-10-28 20:43:15 +0000 |
commit | 1700af3add37a7b6db478d0876536849c3f691fe (patch) | |
tree | 872892de6f9f00fe453544b74e27d35a97a97bc3 | |
parent | dd891561fb3e50f856d7d730f22a12cc1db51788 (diff) | |
download | illumos-joyent-1700af3add37a7b6db478d0876536849c3f691fe.tar.gz |
9916 mdb ::dcmds and ::walkers could have filter options
Reviewed by: Igor Kozhukhov <igor@dilos.org>
Reviewed by: John Levon <john.levon@joyent.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
-rw-r--r-- | usr/src/cmd/mdb/common/mdb/mdb_cmds.c | 7 | ||||
-rw-r--r-- | usr/src/cmd/mdb/common/mdb/mdb_help.c | 217 | ||||
-rw-r--r-- | usr/src/cmd/mdb/common/mdb/mdb_help.h | 4 |
3 files changed, 212 insertions, 16 deletions
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_cmds.c b/usr/src/cmd/mdb/common/mdb/mdb_cmds.c index 063a8eb765..fbd404a107 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_cmds.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_cmds.c @@ -29,6 +29,7 @@ * Copyright (c) 2018 Joyent, Inc. All rights reserved. * Copyright (c) 2013 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * Copyright (c) 2015, 2017 by Delphix. All rights reserved. + * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. */ #include <sys/elf.h> @@ -3100,7 +3101,8 @@ const mdb_dcmd_t mdb_dcmd_builtins[] = { "address", cmd_array }, { "bp", "?[+/-dDestT] [-c cmd] [-n count] sym ...", "breakpoint at the " "specified addresses or symbols", cmd_bp, bp_help }, - { "dcmds", NULL, "list available debugger commands", cmd_dcmds }, + { "dcmds", "[[-n] pattern]", + "list available debugger commands", cmd_dcmds, cmd_dcmds_help }, { "delete", "?[id|all]", "delete traced software events", cmd_delete }, { "dis", "?[-abfw] [-n cnt] [addr]", "disassemble near addr", cmd_dis }, { "disasms", NULL, "list available disassemblers", cmd_disasms }, @@ -3168,7 +3170,8 @@ const mdb_dcmd_t mdb_dcmd_builtins[] = { cmd_vtop }, { "walk", "?name [variable]", "walk data structure", cmd_walk, NULL, cmd_walk_tab }, - { "walkers", NULL, "list available walkers", cmd_walkers }, + { "walkers", "[[-n] pattern]", "list available walkers", + cmd_walkers, cmd_walkers_help }, { "whatis", ":[-aikqv]", "given an address, return information", cmd_whatis, whatis_help }, { "whence", "[-v] name ...", "show source of walk or dcmd", cmd_which }, diff --git a/usr/src/cmd/mdb/common/mdb/mdb_help.c b/usr/src/cmd/mdb/common/mdb/mdb_help.c index 95d3ec6af3..6d3f35d35e 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_help.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_help.c @@ -23,6 +23,7 @@ * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. */ #include <mdb/mdb_modapi.h> @@ -31,6 +32,7 @@ #include <mdb/mdb_err.h> #include <mdb/mdb_help.h> #include <mdb/mdb.h> +#include <regex.h> const char _mdb_help[] = "\nEach debugger command in %s is structured as follows:\n\n" @@ -138,47 +140,234 @@ cmd_dmods(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) return (DCMD_OK); } -/*ARGSUSED*/ +#define FILTER_NAMEONLY 0x1 + +typedef struct filter_data { + const char *pattern; + int flags; +#ifndef _KMDB + regex_t reg; +#endif +} filter_data_t; + +static void +filter_help(void) +{ + mdb_printf("Options:\n" + " -n Match only the name, not the description.\n" +#ifdef _KMDB + " pattern Substring to match against name/description." +#else + " pattern RE to match against name/description." +#endif + "\n"); +} + +void +cmd_dcmds_help(void) +{ + mdb_printf( + "List all of the dcmds that are currently available. If a pattern\n" + "is provided then list only the commands that\n" +#ifdef _KMDB + "contain the provided substring." +#else + "match the provided regular expression." +#endif + "\n"); + filter_help(); +} + +void +cmd_walkers_help(void) +{ + mdb_printf( + "List all of the walkers that are currently available. If a\n" + "pattern is provided then list only the walkers that\n" +#ifdef _KMDB + "contain the provided substring." +#else + "match the provided regular expression." +#endif + "\n"); + filter_help(); +} + static int -print_wdesc(mdb_var_t *v, void *ignored) +print_wdesc(mdb_var_t *v, void *data) { + filter_data_t *f = data; mdb_iwalker_t *iwp = mdb_nv_get_cookie(mdb_nv_get_cookie(v)); + const char *name = mdb_nv_get_name(v); + boolean_t output = FALSE; - if (iwp->iwlk_descr != NULL) - mdb_printf("%-24s - %s\n", mdb_nv_get_name(v), iwp->iwlk_descr); + if (name == NULL || iwp->iwlk_descr == NULL) + return (0); + + if (f->pattern == NULL) { + output = TRUE; + } else { +#ifdef _KMDB + /* + * kmdb doesn't have access to the reg* functions, so we fall + * back to strstr. + */ + if (strstr(name, f->pattern) != NULL || + (!(f->flags & FILTER_NAMEONLY) && + strstr(iwp->iwlk_descr, f->pattern) != NULL)) + output = TRUE; +#else + regmatch_t pmatch; + + if (regexec(&f->reg, name, 1, &pmatch, 0) == 0 || + (!(f->flags & FILTER_NAMEONLY) && + regexec(&f->reg, iwp->iwlk_descr, 1, &pmatch, 0) == 0)) + output = TRUE; +#endif + + } + + if (output) + mdb_printf("%-24s - %s\n", name, iwp->iwlk_descr); return (0); } /*ARGSUSED*/ int -cmd_walkers(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +cmd_walkers(uintptr_t addr __unused, uint_t flags, int argc, + const mdb_arg_t *argv) { - if ((flags & DCMD_ADDRSPEC) || argc != 0) + filter_data_t f; + int i; +#ifndef _KMDB + int err; +#endif + + if (flags & DCMD_ADDRSPEC) return (DCMD_USAGE); - mdb_nv_sort_iter(&mdb.m_walkers, print_wdesc, NULL, UM_SLEEP | UM_GC); + f.pattern = NULL; + f.flags = 0; + + i = mdb_getopts(argc, argv, + 'n', MDB_OPT_SETBITS, FILTER_NAMEONLY, &f.flags, + NULL); + + argc -= i; + argv += i; + + if (argc == 1) { + if (argv->a_type != MDB_TYPE_STRING) + return (DCMD_USAGE); + f.pattern = argv->a_un.a_str; + +#ifndef _KMDB + if ((err = regcomp(&f.reg, f.pattern, REG_EXTENDED)) != 0) { + size_t nbytes; + char *buf; + + nbytes = regerror(err, &f.reg, NULL, 0); + buf = mdb_alloc(nbytes + 1, UM_SLEEP | UM_GC); + (void) regerror(err, &f.reg, buf, nbytes); + mdb_warn("%s\n", buf); + + return (DCMD_ERR); + } +#endif + } else if (argc != 0) { + return (DCMD_USAGE); + } + + mdb_nv_sort_iter(&mdb.m_walkers, print_wdesc, &f, UM_SLEEP | UM_GC); return (DCMD_OK); } -/*ARGSUSED*/ static int -print_ddesc(mdb_var_t *v, void *ignored) +print_ddesc(mdb_var_t *v, void *data) { + filter_data_t *f = data; mdb_idcmd_t *idcp = mdb_nv_get_cookie(mdb_nv_get_cookie(v)); + const char *name = mdb_nv_get_name(v); + boolean_t output = FALSE; - if (idcp->idc_descr != NULL) - mdb_printf("%-24s - %s\n", mdb_nv_get_name(v), idcp->idc_descr); + if (name == NULL || idcp->idc_descr == NULL) + return (0); + + if (f->pattern == NULL) { + output = TRUE; + } else { +#ifdef _KMDB + /* + * kmdb doesn't have access to the reg* functions, so we fall + * back to strstr. + */ + if (strstr(name, f->pattern) != NULL || + (!(f->flags & FILTER_NAMEONLY) && + strstr(idcp->idc_descr, f->pattern) != NULL)) + output = TRUE; +#else + regmatch_t pmatch; + + if (regexec(&f->reg, name, 1, &pmatch, 0) == 0 || + (!(f->flags & FILTER_NAMEONLY) && + regexec(&f->reg, idcp->idc_descr, 1, &pmatch, 0) == 0)) + output = TRUE; +#endif + + } + + if (output) + mdb_printf("%-24s - %s\n", name, idcp->idc_descr); return (0); } /*ARGSUSED*/ int -cmd_dcmds(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +cmd_dcmds(uintptr_t addr __unused, uint_t flags, int argc, + const mdb_arg_t *argv) { - if ((flags & DCMD_ADDRSPEC) || argc != 0) + filter_data_t f; + int i; +#ifndef _KMDB + int err; +#endif + + if (flags & DCMD_ADDRSPEC) + return (DCMD_USAGE); + + f.pattern = NULL; + f.flags = 0; + + i = mdb_getopts(argc, argv, + 'n', MDB_OPT_SETBITS, FILTER_NAMEONLY, &f.flags, + NULL); + + argc -= i; + argv += i; + + if (argc == 1) { + if (argv->a_type != MDB_TYPE_STRING) + return (DCMD_USAGE); + f.pattern = argv->a_un.a_str; + +#ifndef _KMDB + if ((err = regcomp(&f.reg, f.pattern, REG_EXTENDED)) != 0) { + size_t nbytes; + char *buf; + + nbytes = regerror(err, &f.reg, NULL, 0); + buf = mdb_alloc(nbytes + 1, UM_SLEEP | UM_GC); + (void) regerror(err, &f.reg, buf, nbytes); + mdb_warn("%s\n", buf); + + return (DCMD_ERR); + } +#endif + } else if (argc != 0) { return (DCMD_USAGE); + } - mdb_nv_sort_iter(&mdb.m_dcmds, print_ddesc, NULL, UM_SLEEP | UM_GC); + mdb_nv_sort_iter(&mdb.m_dcmds, print_ddesc, &f, UM_SLEEP | UM_GC); return (DCMD_OK); } diff --git a/usr/src/cmd/mdb/common/mdb/mdb_help.h b/usr/src/cmd/mdb/common/mdb/mdb_help.h index 5d63683eba..6ecd6c2575 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_help.h +++ b/usr/src/cmd/mdb/common/mdb/mdb_help.h @@ -23,6 +23,7 @@ * Copyright (c) 1998-1999 by Sun Microsystems, Inc. * All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. */ #ifndef _MDB_HELP_H @@ -44,6 +45,9 @@ extern int cmd_help(uintptr_t, uint_t, int, const mdb_arg_t *); extern int cmd_help_tab(mdb_tab_cookie_t *, uint_t, int, const mdb_arg_t *); extern int cmd_which(uintptr_t, uint_t, int, const mdb_arg_t *); +extern void cmd_dcmds_help(void); +extern void cmd_walkers_help(void); + #endif /* _MDB */ #ifdef __cplusplus |