From 59030a8cd4000fcf92d9b8225c6083f9e6ab86b8 Mon Sep 17 00:00:00 2001 From: aliguori Date: Sun, 5 Apr 2009 18:43:41 +0000 Subject: [PATCH] gdbstub: Rework configuration via command line and monitor (Jan Kiszka) Introduce a more canonical gdbstub configuration (system emulation only) via the new switch '-gdb dev'. Keep '-s' as shorthand for '-gdb tcp::1234'. Use the same syntax also for the corresponding monitor command 'gdbserver'. Its default remains to listen on TCP port 1234. Changes in v4: - Rebased over new command line switches meta file Changes in v3: - Fix documentation Changes in v2: - Support for pipe-based like to gdb (target remote | qemu -gdb stdio) - Properly update the qemu-doc Signed-off-by: Jan Kiszka Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6992 c046a42c-6fe2-441c-8c8c-71466251a162 --- gdbstub.c | 41 +++++++++++++++++++++++++++-------------- monitor.c | 17 +++++++++-------- qemu-options.hx | 24 +++++++++++++++--------- vl.c | 25 ++++++++----------------- 4 files changed, 59 insertions(+), 48 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 518c939f45..316f5e8176 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2337,27 +2337,40 @@ static int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, int len) return len; } -int gdbserver_start(const char *port) +#ifndef _WIN32 +static void gdb_sigterm_handler(int signal) +{ + if (vm_running) + vm_stop(EXCP_INTERRUPT); +} +#endif + +int gdbserver_start(const char *device) { GDBState *s; - char gdbstub_port_name[128]; - int port_num; - char *p; + char gdbstub_device_name[128]; CharDriverState *chr = NULL; CharDriverState *mon_chr; - if (!port || !*port) - return -1; - if (strcmp(port, "none") != 0) { - port_num = strtol(port, &p, 10); - if (*p == 0) { - /* A numeric value is interpreted as a port number. */ - snprintf(gdbstub_port_name, sizeof(gdbstub_port_name), - "tcp::%d,nowait,nodelay,server", port_num); - port = gdbstub_port_name; + if (!device) + return -1; + if (strcmp(device, "none") != 0) { + if (strstart(device, "tcp:", NULL)) { + /* enforce required TCP attributes */ + snprintf(gdbstub_device_name, sizeof(gdbstub_device_name), + "%s,nowait,nodelay,server", device); + device = gdbstub_device_name; } +#ifndef _WIN32 + else if (strcmp(device, "stdio") == 0) { + struct sigaction act; - chr = qemu_chr_open("gdb", port, NULL); + memset(&act, 0, sizeof(act)); + act.sa_handler = gdb_sigterm_handler; + sigaction(SIGINT, &act, NULL); + } +#endif + chr = qemu_chr_open("gdb", device, NULL); if (!chr) return -1; diff --git a/monitor.c b/monitor.c index c6fe968ff2..75c8663a1e 100644 --- a/monitor.c +++ b/monitor.c @@ -570,17 +570,18 @@ static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs) } #ifdef CONFIG_GDBSTUB -static void do_gdbserver(Monitor *mon, const char *port) +static void do_gdbserver(Monitor *mon, const char *device) { - if (!port) - port = DEFAULT_GDBSTUB_PORT; - if (gdbserver_start(port) < 0) { - monitor_printf(mon, "Could not open gdbserver socket on port '%s'\n", - port); - } else if (strcmp(port, "none") == 0) { + if (!device) + device = "tcp::" DEFAULT_GDBSTUB_PORT; + if (gdbserver_start(device) < 0) { + monitor_printf(mon, "Could not open gdbserver on device '%s'\n", + device); + } else if (strcmp(device, "none") == 0) { monitor_printf(mon, "Disabled gdbserver\n"); } else { - monitor_printf(mon, "Waiting gdb connection on port '%s'\n", port); + monitor_printf(mon, "Waiting for gdb connection on device '%s'\n", + device); } } #endif diff --git a/qemu-options.hx b/qemu-options.hx index 32f936fede..51593a3987 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1216,19 +1216,25 @@ STEXI Do not start CPU at startup (you must type 'c' in the monitor). ETEXI -DEF("s", 0, QEMU_OPTION_s, \ - "-s wait gdb connection to port\n") +DEF("gdb", HAS_ARG, QEMU_OPTION_gdb, \ + "-gdb dev wait for gdb connection on 'dev'\n") STEXI -@item -s -Wait gdb connection to port 1234 (@pxref{gdb_usage}). +@item -gdb @var{dev} +Wait for gdb connection on device @var{dev} (@pxref{gdb_usage}). Typical +connections will likely be TCP-based, but also UDP, pseudo TTY, or even +stdio are reasonable use case. The latter is allowing to start qemu from +within gdb and establish the connection via a pipe: +@example +(gdb) target remote | exec qemu -gdb stdio ... +@end example ETEXI -DEF("p", HAS_ARG, QEMU_OPTION_p, \ - "-p port set gdb connection port [default=%s]\n") +DEF("s", 0, QEMU_OPTION_s, \ + "-s shorthand for -gdb tcp::%s\n") STEXI -@item -p @var{port} -Change gdb connection port. @var{port} can be either a decimal number -to specify a TCP port, or a host device (same devices as the serial port). +@item -s +Shorthand for -gdb tcp::1234, i.e. open a gdbserver on TCP port 1234 +(@pxref{gdb_usage}). ETEXI DEF("d", HAS_ARG, QEMU_OPTION_d, \ diff --git a/vl.c b/vl.c index a2de1f35fc..1048bd456c 100644 --- a/vl.c +++ b/vl.c @@ -4233,8 +4233,7 @@ static void termsig_setup(void) int main(int argc, char **argv, char **envp) { #ifdef CONFIG_GDBSTUB - int use_gdbstub; - const char *gdbstub_port; + const char *gdbstub_dev = NULL; #endif uint32_t boot_devices_bitmap = 0; int i; @@ -4317,10 +4316,6 @@ int main(int argc, char **argv, char **envp) initrd_filename = NULL; ram_size = 0; vga_ram_size = VGA_RAM_SIZE; -#ifdef CONFIG_GDBSTUB - use_gdbstub = 0; - gdbstub_port = DEFAULT_GDBSTUB_PORT; -#endif snapshot = 0; nographic = 0; curses = 0; @@ -4653,10 +4648,10 @@ int main(int argc, char **argv, char **envp) break; #ifdef CONFIG_GDBSTUB case QEMU_OPTION_s: - use_gdbstub = 1; + gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT; break; - case QEMU_OPTION_p: - gdbstub_port = optarg; + case QEMU_OPTION_gdb: + gdbstub_dev = optarg; break; #endif case QEMU_OPTION_L: @@ -5370,14 +5365,10 @@ int main(int argc, char **argv, char **envp) } #ifdef CONFIG_GDBSTUB - if (use_gdbstub) { - /* XXX: use standard host:port notation and modify options - accordingly. */ - if (gdbserver_start(gdbstub_port) < 0) { - fprintf(stderr, "qemu: could not open gdbstub device on port '%s'\n", - gdbstub_port); - exit(1); - } + if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) { + fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n", + gdbstub_dev); + exit(1); } #endif