mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-16 06:52:27 +00:00
byhve: add option to specify IP address for gdb
Allow user to specify the IP address available for gdb debugger. Reviewed by: jhb, grehan, rgrimes, bcr (man pages) Differential Revision: https://reviews.freebsd.org/D29607
This commit is contained in:
parent
c541bd368f
commit
2cdff9918e
|
@ -24,7 +24,7 @@
|
||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd April 18, 2021
|
.Dd August 19, 2021
|
||||||
.Dt BHYVE 8
|
.Dt BHYVE 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -137,16 +137,22 @@ Force
|
||||||
.Nm
|
.Nm
|
||||||
to exit when a guest issues an access to an I/O port that is not emulated.
|
to exit when a guest issues an access to an I/O port that is not emulated.
|
||||||
This is intended for debug purposes.
|
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
|
Start a debug server that uses the GDB protocol to export guest state to a
|
||||||
debugger.
|
debugger.
|
||||||
An IPv4 TCP socket will be bound to the supplied
|
An IPv4 TCP socket will be bound to the supplied
|
||||||
|
.Ar bind_address
|
||||||
|
and
|
||||||
.Ar port
|
.Ar port
|
||||||
to listen for debugger connections.
|
to listen for debugger connections.
|
||||||
Only a single debugger may be attached to the debug server at a time.
|
Only a single debugger may be attached to the debug server at a time.
|
||||||
If
|
If the option begins with
|
||||||
.Ar port
|
|
||||||
begins with
|
|
||||||
.Sq w ,
|
.Sq w ,
|
||||||
.Nm
|
.Nm
|
||||||
will pause execution at the first instruction waiting for a debugger to attach.
|
will pause execution at the first instruction waiting for a debugger to attach.
|
||||||
|
|
|
@ -1193,6 +1193,30 @@ parse_simple_config_file(const char *path)
|
||||||
fclose(fp);
|
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
|
static void
|
||||||
set_defaults(void)
|
set_defaults(void)
|
||||||
{
|
{
|
||||||
|
@ -1256,11 +1280,7 @@ main(int argc, char *argv[])
|
||||||
set_config_bool("memory.guest_in_core", true);
|
set_config_bool("memory.guest_in_core", true);
|
||||||
break;
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
if (optarg[0] == 'w') {
|
parse_gdb_options(optarg);
|
||||||
set_config_bool("gdb.wait", true);
|
|
||||||
optarg++;
|
|
||||||
}
|
|
||||||
set_config_value("gdb.port", optarg);
|
|
||||||
break;
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
parse_simple_config_file(optarg);
|
parse_simple_config_file(optarg);
|
||||||
|
@ -1447,10 +1467,7 @@ main(int argc, char *argv[])
|
||||||
if (get_config_bool("acpi_tables"))
|
if (get_config_bool("acpi_tables"))
|
||||||
vmgenc_init(ctx);
|
vmgenc_init(ctx);
|
||||||
|
|
||||||
value = get_config_value("gdb.port");
|
init_gdb(ctx);
|
||||||
if (value != NULL)
|
|
||||||
init_gdb(ctx, atoi(value), get_config_bool_default("gdb.wait",
|
|
||||||
false));
|
|
||||||
|
|
||||||
if (lpc_bootrom()) {
|
if (lpc_bootrom()) {
|
||||||
if (vm_set_capability(ctx, BSP, VM_CAP_UNRESTRICTED_GUEST, 1)) {
|
if (vm_set_capability(ctx, BSP, VM_CAP_UNRESTRICTED_GUEST, 1)) {
|
||||||
|
|
|
@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <netdb.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <pthread_np.h>
|
#include <pthread_np.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
@ -59,6 +60,7 @@ __FBSDID("$FreeBSD$");
|
||||||
#include <vmmapi.h>
|
#include <vmmapi.h>
|
||||||
|
|
||||||
#include "bhyverun.h"
|
#include "bhyverun.h"
|
||||||
|
#include "config.h"
|
||||||
#include "gdb.h"
|
#include "gdb.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "mevent.h"
|
#include "mevent.h"
|
||||||
|
@ -1818,12 +1820,35 @@ limit_gdb_socket(int s)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
init_gdb(struct vmctx *_ctx, int sport, bool wait)
|
init_gdb(struct vmctx *_ctx)
|
||||||
{
|
{
|
||||||
struct sockaddr_in sin;
|
|
||||||
int error, flags, optval, s;
|
int error, flags, optval, s;
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo *gdbaddr;
|
||||||
|
const char *saddr, *value;
|
||||||
|
char *sport;
|
||||||
|
bool wait;
|
||||||
|
|
||||||
debug("==> starting on %d, %swaiting\n", sport, wait ? "" : "not ");
|
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 %s:%s, %swaiting\n",
|
||||||
|
saddr, sport, wait ? "" : "not ");
|
||||||
|
|
||||||
error = pthread_mutex_init(&gdb_lock, NULL);
|
error = pthread_mutex_init(&gdb_lock, NULL);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
|
@ -1832,20 +1857,23 @@ init_gdb(struct vmctx *_ctx, int sport, bool wait)
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
errc(1, error, "gdb cv init");
|
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;
|
ctx = _ctx;
|
||||||
s = socket(PF_INET, SOCK_STREAM, 0);
|
s = socket(gdbaddr->ai_family, gdbaddr->ai_socktype, 0);
|
||||||
if (s < 0)
|
if (s < 0)
|
||||||
err(1, "gdb socket create");
|
err(1, "gdb socket create");
|
||||||
|
|
||||||
optval = 1;
|
optval = 1;
|
||||||
(void)setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
(void)setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||||
|
|
||||||
sin.sin_len = sizeof(sin);
|
if (bind(s, gdbaddr->ai_addr, gdbaddr->ai_addrlen) < 0)
|
||||||
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)
|
|
||||||
err(1, "gdb socket bind");
|
err(1, "gdb socket bind");
|
||||||
|
|
||||||
if (listen(s, 1) < 0)
|
if (listen(s, 1) < 0)
|
||||||
|
@ -1874,4 +1902,6 @@ init_gdb(struct vmctx *_ctx, int sport, bool wait)
|
||||||
#endif
|
#endif
|
||||||
mevent_add(s, EVF_READ, new_connection, NULL);
|
mevent_add(s, EVF_READ, new_connection, NULL);
|
||||||
gdb_active = true;
|
gdb_active = true;
|
||||||
|
freeaddrinfo(gdbaddr);
|
||||||
|
free(sport);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,6 @@ void gdb_cpu_add(int vcpu);
|
||||||
void gdb_cpu_breakpoint(int vcpu, struct vm_exit *vmexit);
|
void gdb_cpu_breakpoint(int vcpu, struct vm_exit *vmexit);
|
||||||
void gdb_cpu_mtrap(int vcpu);
|
void gdb_cpu_mtrap(int vcpu);
|
||||||
void gdb_cpu_suspend(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__ */
|
#endif /* !__GDB_H__ */
|
||||||
|
|
Loading…
Reference in a new issue