summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Fiddaman <omnios@citrus-it.co.uk>2018-10-23 13:54:51 +0000
committerRichard Lowe <richlowe@richlowe.net>2018-10-28 20:43:15 +0000
commit1700af3add37a7b6db478d0876536849c3f691fe (patch)
tree872892de6f9f00fe453544b74e27d35a97a97bc3
parentdd891561fb3e50f856d7d730f22a12cc1db51788 (diff)
downloadillumos-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.c7
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_help.c217
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_help.h4
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