mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-27 02:42:46 +00:00
Add command-line tool ddb(8), which allows DDB(4) scripts to be
managed from userspace. It is largely a wrapper for sysctl() calls, but because the sysctls for adding and removing scripts are awkward to use directly, this provides an easier-to-use interface. MFC after: 3 months
This commit is contained in:
parent
c9b0cc3b96
commit
a1f25b0daa
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=174915
@ -15,6 +15,7 @@ SUBDIR= adjkerntz \
|
||||
clri \
|
||||
comcontrol \
|
||||
conscontrol \
|
||||
ddb \
|
||||
${_devd} \
|
||||
devfs \
|
||||
dhclient \
|
||||
|
8
sbin/ddb/Makefile
Normal file
8
sbin/ddb/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ddb
|
||||
SRCS= ddb.c ddb_script.c
|
||||
MAN= ddb.8
|
||||
WARNS= 3
|
||||
|
||||
.include <bsd.prog.mk>
|
106
sbin/ddb/ddb.8
Normal file
106
sbin/ddb/ddb.8
Normal file
@ -0,0 +1,106 @@
|
||||
.\"-
|
||||
.\" Copyright (c) 2007 Robert N. M. Watson
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd 25 December, 2007
|
||||
.Dt DDB 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ddb
|
||||
.Nd Configure DDB kernel debugger properties
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Cm script
|
||||
.Ar scriptname
|
||||
.Nm
|
||||
.Cm script
|
||||
.Ar scriptname=script
|
||||
.Nm
|
||||
.Cm scripts
|
||||
.Nm
|
||||
.Cm unscript
|
||||
.Ar scriptname
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
configures certain aspects of the
|
||||
.Xr DDB 4
|
||||
kernel debugger from user space that are not configured at compile-time or
|
||||
easily via
|
||||
.Xr sysctl 8
|
||||
MIB entries.
|
||||
.Sh SCRIPTING
|
||||
.Nm
|
||||
can be used to configure aspects of
|
||||
.Xr DDB 4
|
||||
scripting from user space; scripting support is described in more detail in
|
||||
.Xr DDB 4 .
|
||||
Each of the debugger commands is available from the command line:
|
||||
.Bl -tag -width indent
|
||||
.It Cm script Ar scriptname
|
||||
Print the script named
|
||||
.Ar scriptname .
|
||||
.It Cm script Ar scriptname=scriptvalue
|
||||
Define a script named
|
||||
.Ar scriptname ;
|
||||
as many scripts contain characters interpreted in special ways by the shell,
|
||||
it is advisable to enclose
|
||||
.Ar scriptvalue
|
||||
in quotes.
|
||||
.It Cm scripts
|
||||
List currently defined scripts.
|
||||
.It Cm unset Ar scriptname
|
||||
Delete the script named
|
||||
.Ar scriptname .
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
The following example defines a script that will execute when the kernel
|
||||
debugger is entered as a result of a break signal:
|
||||
.Bd -literal -offset indent
|
||||
ddb script kdb.enter.break="show pcpu;bt"
|
||||
.Ed
|
||||
.Pp
|
||||
The following example will delete the script:
|
||||
.Bd -literal -offset indent
|
||||
ddb unscript kdb.enter.break
|
||||
.Ed
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std
|
||||
.Sh SEE ALSO
|
||||
.Xr DDB 4 ,
|
||||
.Xr sysctl 8
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
first appeared in
|
||||
.Fx 8.0 .
|
||||
.Sh AUTHORS
|
||||
.An Robert N M Watson
|
||||
.Sh BUGS
|
||||
Ideally,
|
||||
.Nm
|
||||
would not exist, as all pertinent aspects of
|
||||
.Xr DDB 4
|
||||
could be configured directly via
|
||||
.Xr sysctl 8 .
|
67
sbin/ddb/ddb.c
Normal file
67
sbin/ddb/ddb.c
Normal file
@ -0,0 +1,67 @@
|
||||
/*-
|
||||
* Copyright (c) 2007 Robert N. M. Watson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
|
||||
#include "ddb.h"
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage:\n");
|
||||
fprintf(stderr, "ddb script scriptname\n");
|
||||
fprintf(stderr, "ddb script scriptname=script\n");
|
||||
fprintf(stderr, "ddb scripts\n");
|
||||
fprintf(stderr, "ddb unscript scriptname\n");
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
argc -= 1;
|
||||
argv += 1;
|
||||
if (strcmp(argv[0], "script") == 0)
|
||||
ddb_script(argc, argv);
|
||||
else if (strcmp(argv[0], "scripts") == 0)
|
||||
ddb_scripts(argc, argv);
|
||||
else if (strcmp(argv[0], "unscript") == 0)
|
||||
ddb_unscript(argc, argv);
|
||||
else
|
||||
usage();
|
||||
exit(EX_OK);
|
||||
}
|
37
sbin/ddb/ddb.h
Normal file
37
sbin/ddb/ddb.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*-
|
||||
* Copyright (c) 2007 Robert N. M. Watson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef DDB_H
|
||||
#define DDB_H
|
||||
|
||||
void ddb_script(int argc, char *argv[]);
|
||||
void ddb_scripts(int argc, char *argv[]);
|
||||
void ddb_unscript(int argc, char *argv[]);
|
||||
void usage(void);
|
||||
|
||||
#endif /* DDB_H */
|
160
sbin/ddb/ddb_script.c
Normal file
160
sbin/ddb/ddb_script.c
Normal file
@ -0,0 +1,160 @@
|
||||
/*-
|
||||
* Copyright (c) 2007 Robert N. M. Watson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
|
||||
#include "ddb.h"
|
||||
|
||||
/*
|
||||
* These commands manage DDB(4) scripts from user space. For better or worse,
|
||||
* the setting and unsetting of scripts is only poorly represented using
|
||||
* sysctl(8), and this interface provides a more user-friendly way to
|
||||
* accomplish this management, wrapped around lower-level sysctls. For
|
||||
* completeness, listing of scripts is also included.
|
||||
*/
|
||||
|
||||
#define SYSCTL_SCRIPT "debug.ddb.scripting.script"
|
||||
#define SYSCTL_SCRIPTS "debug.ddb.scripting.scripts"
|
||||
#define SYSCTL_UNSCRIPT "debug.ddb.scripting.unscript"
|
||||
|
||||
/*
|
||||
* Print all scripts (scriptname==NULL) or a specific script.
|
||||
*/
|
||||
static void
|
||||
ddb_list_scripts(const char *scriptname)
|
||||
{
|
||||
char *buffer, *line, *nextline;
|
||||
char *line_script, *line_scriptname;
|
||||
size_t buflen, len;
|
||||
int ret;
|
||||
|
||||
repeat:
|
||||
if (sysctlbyname(SYSCTL_SCRIPTS, NULL, &buflen, NULL, 0) < 0)
|
||||
err(EX_OSERR, "sysctl: %s", SYSCTL_SCRIPTS);
|
||||
if (buflen == 0)
|
||||
return;
|
||||
buffer = malloc(buflen);
|
||||
if (buffer == NULL)
|
||||
err(EX_OSERR, "malloc");
|
||||
bzero(buffer, buflen);
|
||||
len = buflen;
|
||||
ret = sysctlbyname(SYSCTL_SCRIPTS, buffer, &len, NULL, 0);
|
||||
if (ret < 0 && errno != ENOMEM)
|
||||
err(EX_OSERR, "sysctl: %s", SYSCTL_SCRIPTS);
|
||||
if (ret < 0) {
|
||||
free(buffer);
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
/*
|
||||
* We nul'd the buffer before calling sysctl(), so at worst empty.
|
||||
*
|
||||
* If a specific script hasn't been requested, print it all.
|
||||
*/
|
||||
if (scriptname == NULL) {
|
||||
printf("%s", buffer);
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a specific script has been requested, we have to parse the
|
||||
* string to find it.
|
||||
*/
|
||||
nextline = buffer;
|
||||
while ((line = strsep(&nextline, "\n")) != NULL) {
|
||||
line_script = line;
|
||||
line_scriptname = strsep(&line_script, "=");
|
||||
if (line_script == NULL)
|
||||
continue;
|
||||
if (strcmp(scriptname, line_scriptname) != 0)
|
||||
continue;
|
||||
printf("%s\n", line_script);
|
||||
break;
|
||||
}
|
||||
if (line == NULL) {
|
||||
errno = ENOENT;
|
||||
err(EX_DATAERR, "%s", scriptname);
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* "ddb script" can be used to either print or set a script.
|
||||
*/
|
||||
void
|
||||
ddb_script(int argc, char *argv[])
|
||||
{
|
||||
|
||||
if (argc != 2)
|
||||
usage();
|
||||
argv++;
|
||||
argc--;
|
||||
if (strchr(argv[0], '=') != 0) {
|
||||
if (sysctlbyname(SYSCTL_SCRIPT, NULL, NULL, argv[0],
|
||||
strlen(argv[0]) + 1) < 0)
|
||||
err(EX_OSERR, "sysctl: %s", SYSCTL_SCRIPTS);
|
||||
} else
|
||||
ddb_list_scripts(argv[0]);
|
||||
}
|
||||
|
||||
void
|
||||
ddb_scripts(int argc, char *argv[])
|
||||
{
|
||||
|
||||
if (argc != 1)
|
||||
usage();
|
||||
ddb_list_scripts(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
ddb_unscript(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (argc != 2)
|
||||
usage();
|
||||
argv++;
|
||||
argc--;
|
||||
ret = sysctlbyname(SYSCTL_UNSCRIPT, NULL, NULL, argv[0],
|
||||
strlen(argv[0]) + 1);
|
||||
if (ret < 0 && errno == EINVAL) {
|
||||
errno = ENOENT;
|
||||
err(EX_DATAERR, "sysctl: %s", argv[0]);
|
||||
} else if (ret < 0)
|
||||
err(EX_OSERR, "sysctl: %s", SYSCTL_UNSCRIPT);
|
||||
}
|
Loading…
Reference in New Issue
Block a user