Page MenuHomeFreeBSD

D29607.id87131.diff
No OneTemporary

D29607.id87131.diff

Index: usr.sbin/bhyve/bhyve.8
===================================================================
--- usr.sbin/bhyve/bhyve.8
+++ usr.sbin/bhyve/bhyve.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 18, 2021
+.Dd April 6, 2021
.Dt BHYVE 8
.Os
.Sh NAME
@@ -133,16 +133,22 @@
.Nm
to exit when a guest issues an access to an I/O port that is not emulated.
This is intended for debug purposes.
-.It Fl G Ar port
+.It Fl G Xo
+.Sm off
+.Oo Ar w Oc
+.Oo Ar bind_address: Oc
+.Ar port
+.Sm on
+.Xc
Start a debug server that uses the GDB protocol to export guest state to a
debugger.
An IPv4 TCP socket will be bound to the supplied
+.Ar bind_address
+and
.Ar port
to listen for debugger connections.
Only a single debugger may be attached to the debug server at a time.
-If
-.Ar port
-begins with
+If the option begins with
.Sq w ,
.Nm
will pause execution at the first instruction waiting for a debugger to attach.
Index: usr.sbin/bhyve/bhyverun.c
===================================================================
--- usr.sbin/bhyve/bhyverun.c
+++ usr.sbin/bhyve/bhyverun.c
@@ -1255,11 +1255,7 @@
set_config_bool("memory.guest_in_core", true);
break;
case 'G':
- if (optarg[0] == 'w') {
- set_config_bool("gdb.wait", true);
- optarg++;
- }
- set_config_value("gdb.port", optarg);
+ set_config_value("gdb.address", optarg);
break;
case 'k':
parse_simple_config_file(optarg);
@@ -1446,10 +1442,7 @@
if (get_config_bool("acpi_tables"))
vmgenc_init(ctx);
- value = get_config_value("gdb.port");
- if (value != NULL)
- init_gdb(ctx, atoi(value), get_config_bool_default("gdb.wait",
- false));
+ init_gdb(ctx, get_config_value("gdb.address"));
if (lpc_bootrom()) {
if (vm_set_capability(ctx, BSP, VM_CAP_UNRESTRICTED_GUEST, 1)) {
Index: usr.sbin/bhyve/gdb.h
===================================================================
--- usr.sbin/bhyve/gdb.h
+++ usr.sbin/bhyve/gdb.h
@@ -34,6 +34,6 @@
void gdb_cpu_breakpoint(int vcpu, struct vm_exit *vmexit);
void gdb_cpu_mtrap(int vcpu);
void gdb_cpu_suspend(int vcpu);
-void init_gdb(struct vmctx *ctx, int sport, bool wait);
+void init_gdb(struct vmctx *ctx, const char *optarg);
#endif /* !__GDB_H__ */
Index: usr.sbin/bhyve/gdb.c
===================================================================
--- usr.sbin/bhyve/gdb.c
+++ usr.sbin/bhyve/gdb.c
@@ -48,6 +48,7 @@
#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#include <netdb.h>
#include <pthread.h>
#include <pthread_np.h>
#include <stdbool.h>
@@ -1817,13 +1818,60 @@
}
#endif
+static void
+parse_gdb_options(char *optarg, const char **saddr, const char **sport, bool *wait)
+{
+ char *colon;
+
+ if (optarg[0] == 'w') {
+ *wait = true;
+ optarg++;
+ } else {
+ *wait = false;
+ }
+
+ colon = strrchr(optarg, ':');
+ if (colon == NULL) {
+ *saddr = NULL;
+ *sport = optarg;
+ return;
+ }
+
+ *colon = '\0';
+ colon++;
+ *saddr = optarg;
+ *sport = colon;
+}
+
void
-init_gdb(struct vmctx *_ctx, int sport, bool wait)
+init_gdb(struct vmctx *_ctx, const char *optarg)
{
- struct sockaddr_in sin;
int error, flags, s;
+ struct addrinfo hints;
+ struct addrinfo *gdbaddr;
+ const char *saddr, *sport;
+ bool wait;
+ char *str;
- debug("==> starting on %d, %swaiting\n", sport, wait ? "" : "not ");
+ if (optarg == NULL)
+ return;
+
+ str = strdup(optarg);
+ if (str == NULL)
+ errx(4, "Failed to allocate memory");
+
+ parse_gdb_options(str, &saddr, &sport, &wait);
+
+ if (!saddr) {
+#if defined(INET)
+ saddr = "0.0.0.0";
+#elif defined(INET6)
+ saddr = "[::]";
+#endif
+ }
+
+ debug("==> starting on %s:%s, %swaiting\n",
+ saddr, sport, wait ? "" : "not ");
error = pthread_mutex_init(&gdb_lock, NULL);
if (error != 0)
@@ -1832,17 +1880,20 @@
if (error != 0)
errc(1, error, "gdb cv init");
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV | AI_PASSIVE;
+
+ if (getaddrinfo(saddr, sport, &hints, &gdbaddr) != 0)
+ err(1, "gdb address resolve");
+
ctx = _ctx;
- s = socket(PF_INET, SOCK_STREAM, 0);
+ s = socket(gdbaddr->ai_family, gdbaddr->ai_socktype, 0);
if (s < 0)
err(1, "gdb socket create");
- sin.sin_len = sizeof(sin);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_ANY);
- sin.sin_port = htons(sport);
-
- if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
+ if (bind(s, gdbaddr->ai_addr, gdbaddr->ai_addrlen) < 0)
err(1, "gdb socket bind");
if (listen(s, 1) < 0)
@@ -1871,4 +1922,6 @@
#endif
mevent_add(s, EVF_READ, new_connection, NULL);
gdb_active = true;
+ freeaddrinfo(gdbaddr);
+ free(str);
}

File Metadata

Mime Type
text/plain
Expires
Sat, Oct 11, 5:23 AM (18 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23564350
Default Alt Text
D29607.id87131.diff (4 KB)

Event Timeline