#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/cutils.h"
-#include "cpu.h"
#include "trace-root.h"
#ifdef CONFIG_USER_ONLY
#include "qemu.h"
}
return target_xml;
}
+ if (cc->gdb_get_dynamic_xml) {
+ CPUState *cpu = first_cpu;
+ char *xmlname = g_strndup(p, len);
+ const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
+
+ g_free(xmlname);
+ if (xml) {
+ return xml;
+ }
+ }
for (i = 0; ; i++) {
name = xml_builtin[i][0];
if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len))
*p = 0;
#ifdef CONFIG_USER_ONLY
put_packet(s, s->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);
#else
/* In this case wait to send the syscall packet until notification that
put_packet(s, buf);
}
-static void gdb_accept(void)
+static bool gdb_accept(void)
{
GDBState *s;
struct sockaddr_in sockaddr;
fd = accept(gdbserver_fd, (struct sockaddr *)&sockaddr, &len);
if (fd < 0 && errno != EINTR) {
perror("accept");
- return;
+ return false;
} else if (fd >= 0) {
-#ifndef _WIN32
- fcntl(fd, F_SETFD, FD_CLOEXEC);
-#endif
+ qemu_set_cloexec(fd);
break;
}
}
/* set short latency */
- socket_set_nodelay(fd);
+ if (socket_set_nodelay(fd)) {
+ perror("setsockopt");
+ close(fd);
+ return false;
+ }
s = g_malloc0(sizeof(GDBState));
s->c_cpu = first_cpu;
gdb_has_xml = false;
gdbserver_state = s;
+ return true;
}
static int gdbserver_open(int port)
perror("socket");
return -1;
}
-#ifndef _WIN32
- fcntl(fd, F_SETFD, FD_CLOEXEC);
-#endif
+ qemu_set_cloexec(fd);
socket_set_fast_reuse(fd);
if (gdbserver_fd < 0)
return -1;
/* accept connections */
- gdb_accept();
+ if (!gdb_accept()) {
+ close(gdbserver_fd);
+ gdbserver_fd = -1;
+ return -1;
+ }
return 0;
}
sigaction(SIGINT, &act, NULL);
}
#endif
- chr = qemu_chr_new_noreplay("gdb", device);
+ /*
+ * FIXME: it's a bit weird to allow using a mux chardev here
+ * and implicitly setup a monitor. We may want to break this.
+ */
+ chr = qemu_chr_new_noreplay("gdb", device, true);
if (!chr)
return -1;
}