Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F110218368
D21460.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D21460.diff
View Options
Index: head/share/man/man4/ddb.4
===================================================================
--- head/share/man/man4/ddb.4
+++ head/share/man/man4/ddb.4
@@ -24,43 +24,9 @@
.\" any improvements or extensions that they make and grant Carnegie Mellon
.\" the rights to redistribute these changes.
.\"
-.\" changed a \# to #, since groff choked on it.
-.\"
-.\" HISTORY
-.\" ddb.4,v
-.\" Revision 1.1 1993/07/15 18:41:02 brezak
-.\" Man page for DDB
-.\"
-.\" Revision 2.6 92/04/08 08:52:57 rpd
-.\" Changes from OSF.
-.\" [92/01/17 14:19:22 jsb]
-.\" Changes for OSF debugger modifications.
-.\" [91/12/12 tak]
-.\"
-.\" Revision 2.5 91/06/25 13:50:22 rpd
-.\" Added some watchpoint explanation.
-.\" [91/06/25 rpd]
-.\"
-.\" Revision 2.4 91/06/17 15:47:31 jsb
-.\" Added documentation for continue/c, match, search, and watchpoints.
-.\" I've not actually explained what a watchpoint is; maybe Rich can
-.\" do that (hint, hint).
-.\" [91/06/17 10:58:08 jsb]
-.\"
-.\" Revision 2.3 91/05/14 17:04:23 mrt
-.\" Correcting copyright
-.\"
-.\" Revision 2.2 91/02/14 14:10:06 mrt
-.\" Changed to new Mach copyright
-.\" [91/02/12 18:10:12 mrt]
-.\"
-.\" Revision 2.2 90/08/30 14:23:15 dbg
-.\" Created.
-.\" [90/08/30 dbg]
-.\"
.\" $FreeBSD$
.\"
-.Dd October 10, 2019
+.Dd October 17, 2019
.Dt DDB 4
.Os
.Sh NAME
@@ -212,7 +178,12 @@
browse through the history buffer, and move the cursor within the
current line.
.Sh COMMANDS
+.Ss COMMON DEBUGGER COMMANDS
.Bl -tag -width indent -compact
+.It Ic help
+Print a short summary of the available commands and command
+abbreviations.
+.Pp
.It Xo
.Ic examine Ns Op Li / Ns Cm AISabcdghilmorsuxz ...
.Oo Ar addr Oc Ns Op , Ns Ar count
@@ -396,6 +367,9 @@
to get the default address of
.Va dot .
.Pp
+.It Ic halt
+Halt the system.
+.Pp
.It Ic watch Oo Ar addr Oc Ns Op , Ns Ar size
Set a watchpoint for a region.
Execution stops when an attempt to modify the region occurs.
@@ -429,6 +403,20 @@
.It Ic dhwatch Oo Ar addr Oc Ns Op , Ns Ar size
Delete specified hardware watchpoint.
.Pp
+.It Ic kill Ar sig pid
+Send signal
+.Ar sig
+to process
+.Ar pid .
+The signal is acted on upon returning from the debugger.
+This command can be used to kill a process causing resource contention
+in the case of a hung system.
+See
+.Xr signal 3
+for a list of signals.
+Note that the arguments are reversed relative to
+.Xr kill 2 .
+.Pp
.It Ic step Ns Oo Li / Ns Cm p Oc Ns Op , Ns Ar count
.It Ic s Ns Oo Li / Ns Cm p Oc Ns Op , Ns Ar count
Single step
@@ -529,6 +517,25 @@
argument limits the search.
.\"
.Pp
+.It Ic reboot Op Ar seconds
+.It Ic reset Op Ar seconds
+Hard reset the system.
+If the optional argument
+.Ar seconds
+is given, the debugger will wait for this long, at most a week,
+before rebooting.
+.Pp
+.It Ic thread Ar addr | tid
+Switch the debugger to the thread with ID
+.Ar tid ,
+if the argument is a decimal number, or address
+.Ar addr ,
+otherwise.
+.El
+.Pp
+.Ss SPECIALIZED HELPER COMMANDS
+.Pp
+.Bl -tag -width indent -compact
.It Xo
.Ic findstack
.Ar addr
@@ -1174,47 +1181,36 @@
Shows information about lock acquisition coming from the
.Xr witness 4
subsystem.
-.\"
+.El
.Pp
+.Ss OFFLINE DEBUGGING COMMANDS
+.Bl -tag -width indent -compact
.It Ic gdb
-Toggles between remote GDB and DDB mode.
+Switches to remote GDB mode.
In remote GDB mode, another machine is required that runs
.Xr gdb 1
using the remote debug feature, with a connection to the serial
console port on the target machine.
-Currently only available on the
-i386
-architecture.
.Pp
-.It Ic halt
-Halt the system.
+.It Ic netdump Fl s Ar server Oo Fl g Ar gateway Oc Fl c Ar client Fl i Ar iface
+Configure
+.Xr netdump 4
+with the provided parameters, and immediately perform a netdump.
.Pp
-.It Ic kill Ar sig pid
-Send signal
-.Ar sig
-to process
-.Ar pid .
-The signal is acted on upon returning from the debugger.
-This command can be used to kill a process causing resource contention
-in the case of a hung system.
-See
-.Xr signal 3
-for a list of signals.
-Note that the arguments are reversed relative to
-.Xr kill 2 .
+There are some known limitations.
+Principally,
+.Xr netdump 4
+only supports IPv4 at this time.
+The address arguments to the
+.Ic netdump
+command must be dotted decimal IPv4 addresses.
+(Hostnames are not supported.)
+At present, the command only works if the machine is in a panic state.
+Finally, the
+.Nm
+.Ic netdump
+command does not provide any way to configure compression or encryption.
.Pp
-.It Ic reboot Op Ar seconds
-.It Ic reset Op Ar seconds
-Hard reset the system.
-If the optional argument
-.Ar seconds
-is given, the debugger will wait for this long, at most a week,
-before rebooting.
-.Pp
-.It Ic help
-Print a short summary of the available commands and command
-abbreviations.
-.Pp
.It Ic capture on
.It Ic capture off
.It Ic capture reset
@@ -1286,13 +1282,6 @@
reports whether a textdump has been scheduled.
.Ic textdump unset
cancels a request to perform a textdump as the next kernel core dump.
-.Pp
-.It Ic thread Ar addr | tid
-Switch the debugger to the thread with ID
-.Ar tid ,
-if the argument is a decimal number, or address
-.Ar addr ,
-otherwise.
.El
.Sh VARIABLES
The debugger accesses registers and variables as
Index: head/share/man/man4/netdump.4
===================================================================
--- head/share/man/man4/netdump.4
+++ head/share/man/man4/netdump.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 5, 2018
+.Dd October 17, 2019
.Dt NETDUMP 4
.Os
.Sh NAME
@@ -46,7 +46,10 @@
.Nm
clients are configured using the
.Xr dumpon 8
-utility.
+utility or the
+.Ic netdump
+command in
+.Xr ddb 4 .
.Pp
.Nm
client messages consist of a fixed-size header followed by a variable-sized
Index: head/sys/net/debugnet.h
===================================================================
--- head/sys/net/debugnet.h
+++ head/sys/net/debugnet.h
@@ -173,6 +173,29 @@
*/
void debugnet_any_ifnet_update(struct ifnet *);
+/*
+ * DDB parsing helper for common debugnet options.
+ *
+ * -s <server> [-g <gateway] -c <localip> -i <interface>
+ *
+ * Order is not significant. Interface is an online interface that supports
+ * debugnet and can route to the debugnet server. The other parameters are all
+ * IP addresses. For now, all parameters are mandatory, except gateway.
+ *
+ * Provides basic '-h' using provided 'cmd' string.
+ *
+ * Returns zero on success, or errno.
+ */
+struct debugnet_ddb_config {
+ struct ifnet *dd_ifp; /* not ref'd */
+ in_addr_t dd_client;
+ in_addr_t dd_server;
+ in_addr_t dd_gateway;
+ bool dd_has_gateway : 1;
+};
+int debugnet_parse_ddb_cmd(const char *cmd,
+ struct debugnet_ddb_config *result);
+
/* Expose sysctl variables for netdump(4) to alias. */
extern int debugnet_npolls;
extern int debugnet_nretries;
Index: head/sys/net/debugnet.c
===================================================================
--- head/sys/net/debugnet.c
+++ head/sys/net/debugnet.c
@@ -31,6 +31,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_ddb.h"
#include "opt_inet.h"
#include <sys/param.h>
@@ -40,6 +41,11 @@
#include <sys/socket.h>
#include <sys/sysctl.h>
+#ifdef DDB
+#include <ddb/ddb.h>
+#include <ddb/db_lex.h>
+#endif
+
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_arp.h>
@@ -654,3 +660,223 @@
dn_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
}
SYSINIT(dn_evh_init, SI_SUB_EVENTHANDLER + 1, SI_ORDER_ANY, dn_evh_init, NULL);
+
+/*
+ * DDB parsing helpers for debugnet(4) consumers.
+ */
+#ifdef DDB
+struct my_inet_opt {
+ bool has_opt;
+ const char *printname;
+ in_addr_t *result;
+};
+
+static int
+dn_parse_optarg_ipv4(struct my_inet_opt *opt)
+{
+ in_addr_t tmp;
+ unsigned octet;
+ int t;
+
+ tmp = 0;
+ for (octet = 0; octet < 4; octet++) {
+ t = db_read_token_flags(DRT_WSPACE | DRT_DECIMAL);
+ if (t != tNUMBER) {
+ db_printf("%s:%s: octet %u expected number; found %d\n",
+ __func__, opt->printname, octet, t);
+ return (EINVAL);
+ }
+ /*
+ * db_lex lexes '-' distinctly from the number itself, but
+ * let's document that invariant.
+ */
+ MPASS(db_tok_number >= 0);
+
+ if (db_tok_number > UINT8_MAX) {
+ db_printf("%s:%s: octet %u out of range: %jd\n", __func__,
+ opt->printname, octet, (intmax_t)db_tok_number);
+ return (EDOM);
+ }
+
+ /* Constructed host-endian and converted to network later. */
+ tmp = (tmp << 8) | db_tok_number;
+
+ if (octet < 3) {
+ t = db_read_token_flags(DRT_WSPACE);
+ if (t != tDOT) {
+ db_printf("%s:%s: octet %u expected '.'; found"
+ " %d\n", __func__, opt->printname, octet,
+ t);
+ return (EINVAL);
+ }
+ }
+ }
+
+ *opt->result = htonl(tmp);
+ opt->has_opt = true;
+ return (0);
+}
+
+int
+debugnet_parse_ddb_cmd(const char *cmd, struct debugnet_ddb_config *result)
+{
+ struct ifnet *ifp;
+ int t, error;
+ bool want_ifp;
+ char ch;
+
+ struct my_inet_opt opt_client = {
+ .printname = "client",
+ .result = &result->dd_client,
+ },
+ opt_server = {
+ .printname = "server",
+ .result = &result->dd_server,
+ },
+ opt_gateway = {
+ .printname = "gateway",
+ .result = &result->dd_gateway,
+ },
+ *cur_inet_opt;
+
+ ifp = NULL;
+ memset(result, 0, sizeof(*result));
+
+ /*
+ * command [space] [-] [opt] [[space] [optarg]] ...
+ *
+ * db_command has already lexed 'command' for us.
+ */
+ t = db_read_token_flags(DRT_WSPACE);
+ if (t == tWSPACE)
+ t = db_read_token_flags(DRT_WSPACE);
+
+ while (t != tEOL) {
+ if (t != tMINUS) {
+ db_printf("%s: Bad syntax; expected '-', got %d\n",
+ cmd, t);
+ goto usage;
+ }
+
+ t = db_read_token_flags(DRT_WSPACE);
+ if (t != tIDENT) {
+ db_printf("%s: Bad syntax; expected tIDENT, got %d\n",
+ cmd, t);
+ goto usage;
+ }
+
+ if (strlen(db_tok_string) > 1) {
+ db_printf("%s: Bad syntax; expected single option "
+ "flag, got '%s'\n", cmd, db_tok_string);
+ goto usage;
+ }
+
+ want_ifp = false;
+ cur_inet_opt = NULL;
+ switch ((ch = db_tok_string[0])) {
+ default:
+ DNETDEBUG("Unexpected: '%c'\n", ch);
+ /* FALLTHROUGH */
+ case 'h':
+ goto usage;
+ case 'c':
+ cur_inet_opt = &opt_client;
+ break;
+ case 'g':
+ cur_inet_opt = &opt_gateway;
+ break;
+ case 's':
+ cur_inet_opt = &opt_server;
+ break;
+ case 'i':
+ want_ifp = true;
+ break;
+ }
+
+ t = db_read_token_flags(DRT_WSPACE);
+ if (t != tWSPACE) {
+ db_printf("%s: Bad syntax; expected space after "
+ "flag %c, got %d\n", cmd, ch, t);
+ goto usage;
+ }
+
+ if (want_ifp) {
+ t = db_read_token_flags(DRT_WSPACE);
+ if (t != tIDENT) {
+ db_printf("%s: Expected interface but got %d\n",
+ cmd, t);
+ goto usage;
+ }
+
+ CURVNET_SET(vnet0);
+ /*
+ * We *don't* take a ref here because the only current
+ * consumer, db_netdump_cmd, does not need it. It
+ * (somewhat redundantly) extracts the if_name(),
+ * re-lookups the ifp, and takes its own reference.
+ */
+ ifp = ifunit(db_tok_string);
+ CURVNET_RESTORE();
+ if (ifp == NULL) {
+ db_printf("Could not locate interface %s\n",
+ db_tok_string);
+ goto cleanup;
+ }
+ } else {
+ MPASS(cur_inet_opt != NULL);
+ /* Assume IPv4 for now. */
+ error = dn_parse_optarg_ipv4(cur_inet_opt);
+ if (error != 0)
+ goto cleanup;
+ }
+
+ /* Skip (mandatory) whitespace after option, if not EOL. */
+ t = db_read_token_flags(DRT_WSPACE);
+ if (t == tEOL)
+ break;
+ if (t != tWSPACE) {
+ db_printf("%s: Bad syntax; expected space after "
+ "flag %c option; got %d\n", cmd, ch, t);
+ goto usage;
+ }
+ t = db_read_token_flags(DRT_WSPACE);
+ }
+
+ /* Currently, all three are required. */
+ if (!opt_client.has_opt || !opt_server.has_opt || ifp == NULL) {
+ db_printf("%s needs all of client, server, and interface "
+ "specified.\n", cmd);
+ goto usage;
+ }
+
+ result->dd_has_gateway = opt_gateway.has_opt;
+
+ /* Iface validation stolen from netdump_configure. */
+ if (!DEBUGNET_SUPPORTED_NIC(ifp)) {
+ db_printf("%s: interface '%s' does not support debugnet\n",
+ cmd, if_name(ifp));
+ error = ENODEV;
+ goto cleanup;
+ }
+ if ((if_getflags(ifp) & IFF_UP) == 0) {
+ db_printf("%s: interface '%s' link is down\n", cmd,
+ if_name(ifp));
+ error = ENXIO;
+ goto cleanup;
+ }
+
+ result->dd_ifp = ifp;
+
+ /* We parsed the full line to tEOL already, or bailed with an error. */
+ return (0);
+
+usage:
+ db_printf("Usage: %s -s <server> [-g <gateway>] -c <localip> "
+ "-i <interface>\n", cmd);
+ error = EINVAL;
+ /* FALLTHROUGH */
+cleanup:
+ db_skip_to_eol();
+ return (error);
+}
+#endif /* DDB */
Index: head/sys/netinet/netdump/netdump_client.c
===================================================================
--- head/sys/netinet/netdump/netdump_client.c
+++ head/sys/netinet/netdump/netdump_client.c
@@ -34,6 +34,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_ddb.h"
+
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/disk.h>
@@ -52,6 +54,11 @@
#include <sys/syslog.h>
#include <sys/systm.h>
+#ifdef DDB
+#include <ddb/ddb.h>
+#include <ddb/db_lex.h>
+#endif
+
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_arp.h>
@@ -387,15 +394,24 @@
NETDUMP_WUNLOCK();
}
+/*
+ * td of NULL is a sentinel value that indicates a kernel caller (ddb(4) or
+ * modload-based tunable parameters).
+ */
static int
netdump_configure(struct diocskerneldump_arg *conf, struct thread *td)
{
struct ifnet *ifp;
+ struct vnet *vnet;
NETDUMP_ASSERT_WLOCKED();
- CURVNET_SET(TD_TO_VNET(td));
- if (!IS_DEFAULT_VNET(curvnet)) {
+ if (td != NULL)
+ vnet = TD_TO_VNET(td);
+ else
+ vnet = vnet0;
+ CURVNET_SET(vnet);
+ if (td != NULL && !IS_DEFAULT_VNET(curvnet)) {
CURVNET_RESTORE();
return (EINVAL);
}
@@ -699,7 +715,7 @@
/* Ignore errors; we print a message to the console. */
NETDUMP_WLOCK();
- (void)netdump_configure(&conf, curthread);
+ (void)netdump_configure(&conf, NULL);
NETDUMP_WUNLOCK();
}
break;
@@ -729,3 +745,72 @@
MODULE_VERSION(netdump, 1);
DECLARE_MODULE(netdump, netdump_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
+
+#ifdef DDB
+/*
+ * Usage: netdump -s <server> [-g <gateway] -c <localip> -i <interface>
+ *
+ * Order is not significant.
+ *
+ * Currently, this command does not support configuring encryption or
+ * compression.
+ */
+DB_FUNC(netdump, db_netdump_cmd, db_cmd_table, CS_OWN, NULL)
+{
+ static struct diocskerneldump_arg conf;
+ static char blockbuf[NETDUMP_DATASIZE];
+ static union {
+ struct dumperinfo di;
+ /* For valid di_devname. */
+ char di_buf[sizeof(struct dumperinfo) + 1];
+ } u;
+
+ struct debugnet_ddb_config params;
+ int error;
+
+ error = debugnet_parse_ddb_cmd("netdump", ¶ms);
+ if (error != 0) {
+ db_printf("Error configuring netdump: %d\n", error);
+ return;
+ }
+
+ /* Translate to a netdump dumper config. */
+ memset(&conf, 0, sizeof(conf));
+ strlcpy(conf.kda_iface, if_name(params.dd_ifp), sizeof(conf.kda_iface));
+
+ conf.kda_af = AF_INET;
+ conf.kda_server.in4 = (struct in_addr) { params.dd_server };
+ conf.kda_client.in4 = (struct in_addr) { params.dd_client };
+ if (params.dd_has_gateway)
+ conf.kda_gateway.in4 = (struct in_addr) { params.dd_gateway };
+ else
+ conf.kda_gateway.in4 = (struct in_addr) { INADDR_ANY };
+
+ /* Set the global netdump config to these options. */
+ error = netdump_configure(&conf, NULL);
+ if (error != 0) {
+ db_printf("Error enabling netdump: %d\n", error);
+ return;
+ }
+
+ /* Fake the generic dump configuration list entry to avoid malloc. */
+ memset(&u.di_buf, 0, sizeof(u.di_buf));
+ u.di.dumper_start = netdump_start;
+ u.di.dumper_hdr = netdump_write_headers;
+ u.di.dumper = netdump_dumper;
+ u.di.priv = NULL;
+ u.di.blocksize = NETDUMP_DATASIZE;
+ u.di.maxiosize = MAXDUMPPGS * PAGE_SIZE;
+ u.di.mediaoffset = 0;
+ u.di.mediasize = 0;
+ u.di.blockbuf = blockbuf;
+
+ dumper_ddb_insert(&u.di);
+
+ error = doadump(false);
+
+ dumper_ddb_remove(&u.di);
+ if (error != 0)
+ db_printf("Cannot dump: %d\n", error);
+}
+#endif /* DDB */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 16, 6:44 AM (13 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16670366
Default Alt Text
D21460.diff (15 KB)
Attached To
Mode
D21460: Add ddb(4) 'netdump' command to netdump a core without preconfiguration
Attached
Detach File
Event Timeline
Log In to Comment