From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LkyZI-0006xd-Bx for qemu-devel@nongnu.org; Sat, 21 Mar 2009 06:36:44 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LkyZC-0006wZ-Rt for qemu-devel@nongnu.org; Sat, 21 Mar 2009 06:36:43 -0400 Received: from [199.232.76.173] (port=54919 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LkyZC-0006wM-EP for qemu-devel@nongnu.org; Sat, 21 Mar 2009 06:36:38 -0400 Received: from fmmailgate01.web.de ([217.72.192.221]:41242) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LkyZB-0005u9-NS for qemu-devel@nongnu.org; Sat, 21 Mar 2009 06:36:38 -0400 Received: from smtp07.web.de (fmsmtp07.dlan.cinetic.de [172.20.5.215]) by fmmailgate01.web.de (Postfix) with ESMTP id A6F30FECF16B for ; Sat, 21 Mar 2009 11:36:34 +0100 (CET) Received: from [88.64.26.35] (helo=[192.168.1.2]) by smtp07.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #277) id 1LkyZ8-0001hg-00 for qemu-devel@nongnu.org; Sat, 21 Mar 2009 11:36:34 +0100 Message-ID: <49C4C331.6080701@web.de> Date: Sat, 21 Mar 2009 11:36:33 +0100 From: Jan Kiszka MIME-Version: 1.0 References: <49C0D693.2030301@siemens.com> <49C4B806.5010107@web.de> In-Reply-To: <49C4B806.5010107@web.de> Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Sender: jan.kiszka@web.de Subject: [Qemu-devel] [PATCH 2/2 -v3] gdbstub: Rework configuration via command line and monitor Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Jan Kiszka wrote: > +@item -gdb @var{dev} > + > +Wait for gdb connection on device @var{dev} (@pxref{gdb_usage}). Typical > +connections will likely be TCP-based, but also unix sockets or even stdio > +are reasonable use case. The latter is allowing to start qemu from within > +gdb and establish the connection via a pipe: > + > +(gdb) target remote | exec qemu -gdb stdio ... > + In fact, unix sockets are not supported by gdb, but udp or /dev/pts/n. --------> Introduce a more powerful 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 port 1234. 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 --- gdbstub.c | 41 +++++++++++++++++++++++++++-------------- monitor.c | 19 ++++++++++--------- qemu-doc.texi | 14 ++++++++++++-- vl.c | 33 ++++++++++++--------------------- 4 files changed, 61 insertions(+), 46 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index e8ceaae..cea375f 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2395,27 +2395,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 c6fe968..75c8663 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) -{ - 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) { +static void do_gdbserver(Monitor *mon, const char *device) +{ + 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-doc.texi b/qemu-doc.texi index 8efc943..8049a0d 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -1097,8 +1097,18 @@ from a script. @item -S Do not start CPU at startup (you must type 'c' in the monitor). +@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: + +(gdb) target remote | exec qemu -gdb stdio ... + @item -s -Wait gdb connection to port 1234 (@pxref{gdb_usage}). +Shorthand for -gdb tcp::1234, i.e. open a gdbserver on TCP port 1234 +(@pxref{gdb_usage}). @item -p @var{port} Change gdb connection port. @var{port} can be either a decimal number @@ -3114,7 +3124,7 @@ MV88W8xx8 Ethernet controller @item MV88W8618 audio controller, WM8750 CODEC and mixer @item -128??64 display with brightness control +128x64 display with brightness control @item 2 buttons, 2 navigation wheels with button function @end itemize diff --git a/vl.c b/vl.c index abc7f5d..6e31a00 100644 --- a/vl.c +++ b/vl.c @@ -4073,8 +4073,8 @@ static void help(int exitcode) "-monitor dev redirect the monitor to char device 'dev'\n" "-pidfile file write PID to 'file'\n" "-S freeze CPU at startup (use 'c' to start execution)\n" - "-s wait gdb connection to port\n" - "-p port set gdb connection port [default=%s]\n" + "-gdb dev wait for gdb connection on 'dev'\n" + "-s shorthand for -gdb tcp::%s\n" "-d item1,... output log to %s (use -d ? for a list of log items)\n" "-hdachs c,h,s[,t]\n" " force hard disk 0 physical geometry and the optional BIOS\n" @@ -4214,7 +4214,7 @@ enum { QEMU_OPTION_pidfile, QEMU_OPTION_S, QEMU_OPTION_s, - QEMU_OPTION_p, + QEMU_OPTION_gdb, QEMU_OPTION_d, QEMU_OPTION_hdachs, QEMU_OPTION_L, @@ -4336,7 +4336,7 @@ static const QEMUOption qemu_options[] = { { "pidfile", HAS_ARG, QEMU_OPTION_pidfile }, { "S", 0, QEMU_OPTION_S }, { "s", 0, QEMU_OPTION_s }, - { "p", HAS_ARG, QEMU_OPTION_p }, + { "gdb", HAS_ARG, QEMU_OPTION_gdb }, { "d", HAS_ARG, QEMU_OPTION_d }, { "hdachs", HAS_ARG, QEMU_OPTION_hdachs }, { "L", HAS_ARG, QEMU_OPTION_L }, @@ -4607,8 +4607,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; @@ -4687,10 +4686,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; @@ -5023,10 +5018,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: @@ -5732,14 +5727,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