From: "Alex Bennée" <alex.bennee@linaro.org>
To: qemu-devel@nongnu.org
Cc: "Damien Hedde" <damien.hedde@greensocs.com>,
"Richard Henderson" <richard.henderson@linaro.org>,
qemu-arm@nongnu.org, "Alex Bennée" <alex.bennee@linaro.org>,
"Philippe Mathieu-Daudé" <philmd@redhat.com>
Subject: [PATCH v1 06/28] gdbstub: make GDBState static and have common init function
Date: Mon, 16 Mar 2020 17:21:33 +0000 [thread overview]
Message-ID: <20200316172155.971-7-alex.bennee@linaro.org> (raw)
In-Reply-To: <20200316172155.971-1-alex.bennee@linaro.org>
Instead of allocating make this entirely static. We shall reduce the
size of the structure in later commits and dynamically allocate parts
of it. We introduce an init and reset helper function to keep all the
manipulation in one place.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Damien Hedde <damien.hedde@greensocs.com>
---
v2
- made entirely static, dropped dh/rth r-b tags due to changes
---
gdbstub.c | 168 ++++++++++++++++++++++++++----------------------------
1 file changed, 81 insertions(+), 87 deletions(-)
diff --git a/gdbstub.c b/gdbstub.c
index 22a2d630cdc..57d6e50ddfc 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -342,6 +342,7 @@ enum RSState {
RS_CHKSUM2,
};
typedef struct GDBState {
+ bool init; /* have we been initialised? */
CPUState *c_cpu; /* current CPU for step/continue ops */
CPUState *g_cpu; /* current CPU for other ops */
CPUState *query_cpu; /* for q{f|s}ThreadInfo */
@@ -372,7 +373,23 @@ typedef struct GDBState {
*/
static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;
-static GDBState *gdbserver_state;
+static GDBState gdbserver_state;
+
+static void init_gdbserver_state(void)
+{
+ g_assert(!gdbserver_state.init);
+ memset(&gdbserver_state, 0, sizeof(GDBState));
+ gdbserver_state.init = true;
+}
+
+#ifndef CONFIG_USER_ONLY
+static void reset_gdbserver_state(void)
+{
+ g_free(gdbserver_state.processes);
+ gdbserver_state.processes = NULL;
+ gdbserver_state.process_num = 0;
+}
+#endif
bool gdb_has_xml;
@@ -425,8 +442,8 @@ int use_gdb_syscalls(void)
/* -semihosting-config target=auto */
/* On the first call check if gdb is connected and remember. */
if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
- gdb_syscall_mode = (gdbserver_state ? GDB_SYS_ENABLED
- : GDB_SYS_DISABLED);
+ gdb_syscall_mode = gdbserver_state.init ?
+ GDB_SYS_ENABLED : GDB_SYS_DISABLED;
}
return gdb_syscall_mode == GDB_SYS_ENABLED;
}
@@ -984,7 +1001,7 @@ static int gdb_breakpoint_insert(int type, target_ulong addr, target_ulong len)
int err = 0;
if (kvm_enabled()) {
- return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
+ return kvm_insert_breakpoint(gdbserver_state.c_cpu, addr, len, type);
}
switch (type) {
@@ -1021,7 +1038,7 @@ static int gdb_breakpoint_remove(int type, target_ulong addr, target_ulong len)
int err = 0;
if (kvm_enabled()) {
- return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
+ return kvm_remove_breakpoint(gdbserver_state.c_cpu, addr, len, type);
}
switch (type) {
@@ -1074,7 +1091,7 @@ static void gdb_breakpoint_remove_all(void)
CPUState *cpu;
if (kvm_enabled()) {
- kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
+ kvm_remove_all_breakpoints(gdbserver_state.c_cpu);
return;
}
@@ -2601,7 +2618,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
void gdb_set_stop_cpu(CPUState *cpu)
{
- GDBProcess *p = gdb_get_cpu_process(gdbserver_state, cpu);
+ GDBProcess *p = gdb_get_cpu_process(&gdbserver_state, cpu);
if (!p->attached) {
/*
@@ -2611,14 +2628,14 @@ void gdb_set_stop_cpu(CPUState *cpu)
return;
}
- gdbserver_state->c_cpu = cpu;
- gdbserver_state->g_cpu = cpu;
+ gdbserver_state.c_cpu = cpu;
+ gdbserver_state.g_cpu = cpu;
}
#ifndef CONFIG_USER_ONLY
static void gdb_vm_state_change(void *opaque, int running, RunState state)
{
- GDBState *s = gdbserver_state;
+ GDBState *s = &gdbserver_state;
CPUState *cpu = s->c_cpu;
char buf[256];
char thread_id[16];
@@ -2722,17 +2739,16 @@ void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
char *p_end;
target_ulong addr;
uint64_t i64;
- GDBState *s;
- s = gdbserver_state;
- if (!s)
+ if (!gdbserver_state.init)
return;
- s->current_syscall_cb = cb;
+
+ gdbserver_state.current_syscall_cb = cb;
#ifndef CONFIG_USER_ONLY
vm_stop(RUN_STATE_DEBUG);
#endif
- p = s->syscall_buf;
- p_end = &s->syscall_buf[sizeof(s->syscall_buf)];
+ p = &gdbserver_state.syscall_buf[0];
+ p_end = &gdbserver_state.syscall_buf[sizeof(gdbserver_state.syscall_buf)];
*(p++) = 'F';
while (*fmt) {
if (*fmt == '%') {
@@ -2765,14 +2781,14 @@ void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
}
*p = 0;
#ifdef CONFIG_USER_ONLY
- put_packet(s, s->syscall_buf);
+ put_packet(&gdbserver_state, gdbserver_state.syscall_buf);
/* Return control to gdb for it to process the syscall request.
* Since the protocol requires that gdb hands control back to us
* using a "here are the results" F packet, we don't need to check
* gdb_handlesig's return value (which is the signal to deliver if
* execution was resumed via a continue packet).
*/
- gdb_handlesig(s->c_cpu, 0);
+ gdb_handlesig(gdbserver_state.c_cpu, 0);
#else
/* In this case wait to send the syscall packet until notification that
the CPU has stopped. This must be done because if the packet is sent
@@ -2780,7 +2796,7 @@ void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
is still in the running state, which can cause packets to be dropped
and state transition 'T' packets to be sent while the syscall is still
being processed. */
- qemu_cpu_kick(s->c_cpu);
+ qemu_cpu_kick(gdbserver_state.c_cpu);
#endif
}
@@ -2941,15 +2957,13 @@ static void gdb_read_byte(GDBState *s, uint8_t ch)
/* Tell the remote gdb that the process has exited. */
void gdb_exit(CPUArchState *env, int code)
{
- GDBState *s;
char buf[4];
- s = gdbserver_state;
- if (!s) {
+ if (!gdbserver_state.init) {
return;
}
#ifdef CONFIG_USER_ONLY
- if (gdbserver_fd < 0 || s->fd < 0) {
+ if (gdbserver_fd < 0 || gdbserver_state.fd < 0) {
return;
}
#endif
@@ -2957,10 +2971,10 @@ void gdb_exit(CPUArchState *env, int code)
trace_gdbstub_op_exiting((uint8_t)code);
snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
- put_packet(s, buf);
+ put_packet(&gdbserver_state, buf);
#ifndef CONFIG_USER_ONLY
- qemu_chr_fe_deinit(&s->chr, true);
+ qemu_chr_fe_deinit(&gdbserver_state.chr, true);
#endif
}
@@ -2993,12 +3007,10 @@ static void create_default_process(GDBState *s)
int
gdb_handlesig(CPUState *cpu, int sig)
{
- GDBState *s;
char buf[256];
int n;
- s = gdbserver_state;
- if (gdbserver_fd < 0 || s->fd < 0) {
+ if (gdbserver_fd < 0 || gdbserver_state.fd < 0) {
return sig;
}
@@ -3008,58 +3020,55 @@ gdb_handlesig(CPUState *cpu, int sig)
if (sig != 0) {
snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb(sig));
- put_packet(s, buf);
+ put_packet(&gdbserver_state, buf);
}
/* put_packet() might have detected that the peer terminated the
connection. */
- if (s->fd < 0) {
+ if (gdbserver_state.fd < 0) {
return sig;
}
sig = 0;
- s->state = RS_IDLE;
- s->running_state = 0;
- while (s->running_state == 0) {
- n = read(s->fd, buf, 256);
+ gdbserver_state.state = RS_IDLE;
+ gdbserver_state.running_state = 0;
+ while (gdbserver_state.running_state == 0) {
+ n = read(gdbserver_state.fd, buf, 256);
if (n > 0) {
int i;
for (i = 0; i < n; i++) {
- gdb_read_byte(s, buf[i]);
+ gdb_read_byte(&gdbserver_state, buf[i]);
}
} else {
/* XXX: Connection closed. Should probably wait for another
connection before continuing. */
if (n == 0) {
- close(s->fd);
+ close(gdbserver_state.fd);
}
- s->fd = -1;
+ gdbserver_state.fd = -1;
return sig;
}
}
- sig = s->signal;
- s->signal = 0;
+ sig = gdbserver_state.signal;
+ gdbserver_state.signal = 0;
return sig;
}
/* Tell the remote gdb that the process has exited due to SIG. */
void gdb_signalled(CPUArchState *env, int sig)
{
- GDBState *s;
char buf[4];
- s = gdbserver_state;
- if (gdbserver_fd < 0 || s->fd < 0) {
+ if (gdbserver_fd < 0 || gdbserver_state.fd < 0) {
return;
}
snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
- put_packet(s, buf);
+ put_packet(&gdbserver_state, buf);
}
static bool gdb_accept(void)
{
- GDBState *s;
struct sockaddr_in sockaddr;
socklen_t len;
int fd;
@@ -3083,15 +3092,13 @@ static bool gdb_accept(void)
return false;
}
- s = g_malloc0(sizeof(GDBState));
- create_default_process(s);
- s->processes[0].attached = true;
- s->c_cpu = gdb_first_attached_cpu(s);
- s->g_cpu = s->c_cpu;
- s->fd = fd;
+ init_gdbserver_state();
+ create_default_process(&gdbserver_state);
+ gdbserver_state.processes[0].attached = true;
+ gdbserver_state.c_cpu = gdb_first_attached_cpu(&gdbserver_state);
+ gdbserver_state.g_cpu = gdbserver_state.c_cpu;
+ gdbserver_state.fd = fd;
gdb_has_xml = false;
-
- gdbserver_state = s;
return true;
}
@@ -3144,13 +3151,11 @@ int gdbserver_start(int port)
/* Disable gdb stub for child processes. */
void gdbserver_fork(CPUState *cpu)
{
- GDBState *s = gdbserver_state;
-
- if (gdbserver_fd < 0 || s->fd < 0) {
+ if (gdbserver_fd < 0 || gdbserver_state.fd < 0) {
return;
}
- close(s->fd);
- s->fd = -1;
+ close(gdbserver_state.fd);
+ gdbserver_state.fd = -1;
cpu_breakpoint_remove_all(cpu, BP_GDB);
cpu_watchpoint_remove_all(cpu, BP_GDB);
}
@@ -3167,7 +3172,7 @@ static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
int i;
for (i = 0; i < size; i++) {
- gdb_read_byte(gdbserver_state, buf[i]);
+ gdb_read_byte(&gdbserver_state, buf[i]);
}
}
@@ -3210,13 +3215,13 @@ static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
const char *p = (const char *)buf;
int max_sz;
- max_sz = (sizeof(gdbserver_state->last_packet) - 2) / 2;
+ max_sz = (sizeof(gdbserver_state.last_packet) - 2) / 2;
for (;;) {
if (len <= max_sz) {
- gdb_monitor_output(gdbserver_state, p, len);
+ gdb_monitor_output(&gdbserver_state, p, len);
break;
}
- gdb_monitor_output(gdbserver_state, p, max_sz);
+ gdb_monitor_output(&gdbserver_state, p, max_sz);
p += max_sz;
len -= max_sz;
}
@@ -3308,18 +3313,10 @@ static void create_processes(GDBState *s)
create_default_process(s);
}
-static void cleanup_processes(GDBState *s)
-{
- g_free(s->processes);
- s->process_num = 0;
- s->processes = NULL;
-}
-
int gdbserver_start(const char *device)
{
trace_gdbstub_op_start(device);
- GDBState *s;
char gdbstub_device_name[128];
Chardev *chr = NULL;
Chardev *mon_chr;
@@ -3357,10 +3354,8 @@ int gdbserver_start(const char *device)
return -1;
}
- s = gdbserver_state;
- if (!s) {
- s = g_malloc0(sizeof(GDBState));
- gdbserver_state = s;
+ if (!gdbserver_state.init) {
+ init_gdbserver_state();
qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
@@ -3369,31 +3364,30 @@ int gdbserver_start(const char *device)
NULL, NULL, &error_abort);
monitor_init_hmp(mon_chr, false, &error_abort);
} else {
- qemu_chr_fe_deinit(&s->chr, true);
- mon_chr = s->mon_chr;
- cleanup_processes(s);
- memset(s, 0, sizeof(GDBState));
- s->mon_chr = mon_chr;
+ qemu_chr_fe_deinit(&gdbserver_state.chr, true);
+ mon_chr = gdbserver_state.mon_chr;
+ reset_gdbserver_state();
}
- create_processes(s);
+ create_processes(&gdbserver_state);
if (chr) {
- qemu_chr_fe_init(&s->chr, chr, &error_abort);
- qemu_chr_fe_set_handlers(&s->chr, gdb_chr_can_receive, gdb_chr_receive,
- gdb_chr_event, NULL, s, NULL, true);
+ qemu_chr_fe_init(&gdbserver_state.chr, chr, &error_abort);
+ qemu_chr_fe_set_handlers(&gdbserver_state.chr, gdb_chr_can_receive,
+ gdb_chr_receive, gdb_chr_event,
+ NULL, &gdbserver_state, NULL, true);
}
- s->state = chr ? RS_IDLE : RS_INACTIVE;
- s->mon_chr = mon_chr;
- s->current_syscall_cb = NULL;
+ gdbserver_state.state = chr ? RS_IDLE : RS_INACTIVE;
+ gdbserver_state.mon_chr = mon_chr;
+ gdbserver_state.current_syscall_cb = NULL;
return 0;
}
void gdbserver_cleanup(void)
{
- if (gdbserver_state) {
- put_packet(gdbserver_state, "W00");
+ if (gdbserver_state.init) {
+ put_packet(&gdbserver_state, "W00");
}
}
--
2.20.1
next prev parent reply other threads:[~2020-03-16 17:49 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-16 17:21 [PATCH v1 00/28 for 5.0] testing and gdbstub Alex Bennée
2020-03-16 17:21 ` [PATCH v1 01/28] tests/docker: Install tools to cross-debug and build Linux kernels Alex Bennée
2020-03-16 17:21 ` [PATCH v1 02/28] tests/docker: Update VirGL git repository URL Alex Bennée
2020-03-16 17:21 ` [PATCH v1 03/28] tests/docker: Remove obsolete VirGL --with-glx configure option Alex Bennée
2020-03-16 17:21 ` [PATCH v1 04/28] tests/docker: Update VirGL to v0.8.0 Alex Bennée
2020-03-16 17:21 ` [PATCH v1 05/28] travis.yml: Set G_MESSAGES_DEBUG do report GLib errors Alex Bennée
2020-03-16 17:21 ` Alex Bennée [this message]
2020-03-16 17:21 ` [PATCH v1 07/28] gdbstub: stop passing GDBState * around and use global Alex Bennée
2020-03-16 17:21 ` [PATCH v1 08/28] gdbstub: move str_buf to GDBState and use GString Alex Bennée
2020-03-16 17:21 ` [PATCH v1 09/28] gdbstub: move mem_buf to GDBState and use GByteArray Alex Bennée
2020-03-16 17:21 ` [PATCH v1 10/28] gdbstub: add helper for 128 bit registers Alex Bennée
2020-03-16 17:21 ` [PATCH v1 11/28] target/arm: use gdb_get_reg helpers Alex Bennée
2020-03-16 17:21 ` [PATCH v1 12/28] target/m68k: " Alex Bennée
2020-03-17 9:48 ` Philippe Mathieu-Daudé
2020-03-16 17:21 ` [PATCH v1 13/28] target/i386: " Alex Bennée
2020-03-17 9:53 ` Philippe Mathieu-Daudé
2020-03-17 10:05 ` Philippe Mathieu-Daudé
2020-03-16 17:21 ` [PATCH v1 14/28] gdbstub: extend GByteArray to read register helpers Alex Bennée
2020-03-16 17:21 ` [PATCH v1 15/28] target/arm: prepare for multiple dynamic XMLs Alex Bennée
2020-03-16 17:21 ` [PATCH v1 16/28] target/arm: explicitly encode regnum in our XML Alex Bennée
2020-03-16 17:21 ` [PATCH v1 17/28] target/arm: default SVE length to 64 bytes for linux-user Alex Bennée
2020-03-16 17:21 ` [PATCH v1 18/28] target/arm: generate xml description of our SVE registers Alex Bennée
2020-03-16 17:21 ` [PATCH v1 19/28] target/arm: don't bother with id_aa64pfr0_read for USER_ONLY Alex Bennée
2020-03-17 9:56 ` Philippe Mathieu-Daudé
2020-03-16 17:21 ` [PATCH v1 20/28] tests/tcg/aarch64: userspace system register test Alex Bennée
2020-03-17 10:24 ` Philippe Mathieu-Daudé
2020-03-17 11:03 ` Alex Bennée
2020-03-17 11:43 ` Philippe Mathieu-Daudé
2020-03-16 17:21 ` [PATCH v1 21/28] configure: allow user to specify what gdb to use Alex Bennée
2020-03-16 18:27 ` Peter Maydell
2020-03-17 9:46 ` Alex Bennée
2020-03-16 17:21 ` [PATCH v1 22/28] tests/guest-debug: add a simple test runner Alex Bennée
2020-03-17 10:30 ` Philippe Mathieu-Daudé
2020-03-16 17:21 ` [PATCH v1 23/28] tests/tcg/aarch64: add a gdbstub testcase for SVE registers Alex Bennée
2020-03-17 10:30 ` Philippe Mathieu-Daudé
2020-03-16 17:21 ` [PATCH v1 24/28] tests/tcg/aarch64: add SVE iotcl test Alex Bennée
2020-03-17 10:29 ` Philippe Mathieu-Daudé
2020-03-17 10:45 ` Aleksandar Markovic
2020-03-17 10:49 ` Peter Maydell
2020-03-17 13:57 ` Alex Bennée
2020-03-17 13:40 ` Aleksandar Markovic
2020-03-16 17:21 ` [PATCH v1 25/28] tests/tcg/aarch64: add test-sve-ioctl guest-debug test Alex Bennée
2020-03-16 17:21 ` [PATCH v1 26/28] gdbstub: change GDBState.last_packet to GByteArray Alex Bennée
2020-03-16 17:21 ` [PATCH v1 27/28] gdbstub: do not split gdb_monitor_write payload Alex Bennée
2020-03-16 17:21 ` [PATCH v1 28/28] gdbstub: Fix single-step issue by confirming 'vContSupported+' feature to gdb Alex Bennée
2020-03-16 21:26 ` [PATCH v1 00/28 for 5.0] testing and gdbstub no-reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200316172155.971-7-alex.bennee@linaro.org \
--to=alex.bennee@linaro.org \
--cc=damien.hedde@greensocs.com \
--cc=philmd@redhat.com \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).