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 <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6992 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
aliguori 2009-04-05 18:43:41 +00:00
parent bc14ca2453
commit 59030a8cd4
4 changed files with 59 additions and 48 deletions

View File

@ -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;

View File

@ -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

View File

@ -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, \

25
vl.c
View File

@ -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