Page MenuHomeFreeBSD

D29607.diff
No OneTemporary

D29607.diff

diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8
--- a/usr.sbin/bhyve/bhyve.8
+++ b/usr.sbin/bhyve/bhyve.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 18, 2021
+.Dd August 19, 2021
.Dt BHYVE 8
.Os
.Sh NAME
@@ -137,16 +137,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.
diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c
--- a/usr.sbin/bhyve/bhyverun.c
+++ b/usr.sbin/bhyve/bhyverun.c
@@ -1193,6 +1193,30 @@
fclose(fp);
}
+static void
+parse_gdb_options(char *optarg)
+{
+ const char *sport;
+ char *colon;
+
+ if (optarg[0] == 'w') {
+ set_config_bool("gdb.wait", true);
+ optarg++;
+ }
+
+ colon = strrchr(optarg, ':');
+ if (colon == NULL) {
+ sport = optarg;
+ } else {
+ *colon = '\0';
+ colon++;
+ sport = colon;
+ set_config_value("gdb.address", optarg);
+ }
+
+ set_config_value("gdb.port", sport);
+}
+
static void
set_defaults(void)
{
@@ -1256,11 +1280,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);
+ parse_gdb_options(optarg);
break;
case 'k':
parse_simple_config_file(optarg);
@@ -1447,10 +1467,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);
if (lpc_bootrom()) {
if (vm_set_capability(ctx, BSP, VM_CAP_UNRESTRICTED_GUEST, 1)) {
diff --git a/usr.sbin/bhyve/gdb.h b/usr.sbin/bhyve/gdb.h
--- a/usr.sbin/bhyve/gdb.h
+++ b/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);
#endif /* !__GDB_H__ */
diff --git a/usr.sbin/bhyve/gdb.c b/usr.sbin/bhyve/gdb.c
--- a/usr.sbin/bhyve/gdb.c
+++ b/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>
@@ -59,6 +60,7 @@
#include <vmmapi.h>
#include "bhyverun.h"
+#include "config.h"
#include "gdb.h"
#include "mem.h"
#include "mevent.h"
@@ -1818,12 +1820,35 @@
#endif
void
-init_gdb(struct vmctx *_ctx, int sport, bool wait)
+init_gdb(struct vmctx *_ctx)
{
- struct sockaddr_in sin;
int error, flags, optval, s;
+ struct addrinfo hints;
+ struct addrinfo *gdbaddr;
+ const char *saddr, *value;
+ char *sport;
+ bool wait;
+
+ value = get_config_value("gdb.port");
+ if (value == NULL)
+ return;
+ sport = strdup(value);
+ if (sport == NULL)
+ errx(4, "Failed to allocate memory");
+
+ wait = get_config_bool_default("gdb.wait", false);
+
+ saddr = get_config_value("gdb.address");
+ if (saddr == NULL) {
+#if defined(INET)
+ saddr = "0.0.0.0";
+#elif defined(INET6)
+ saddr = "[::]";
+#endif
+ }
- debug("==> starting on %d, %swaiting\n", sport, wait ? "" : "not ");
+ debug("==> starting on %s:%s, %swaiting\n",
+ saddr, sport, wait ? "" : "not ");
error = pthread_mutex_init(&gdb_lock, NULL);
if (error != 0)
@@ -1832,20 +1857,23 @@
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");
optval = 1;
(void)setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
- 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)
@@ -1874,4 +1902,6 @@
#endif
mevent_add(s, EVF_READ, new_connection, NULL);
gdb_active = true;
+ freeaddrinfo(gdbaddr);
+ free(sport);
}

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 28, 8:47 PM (37 m, 6 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15626005
Default Alt Text
D29607.diff (4 KB)

Event Timeline