Commit 59030a8c authored by Anthony Liguori's avatar Anthony Liguori
Browse files

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


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6992 c046a42c-6fe2-441c-8c8c-71466251a162
parent bc14ca24
Loading
Loading
Loading
Loading
+27 −14
Original line number Diff line number Diff line
@@ -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)
    if (!device)
        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 (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;

+10 −9
Original line number Diff line number Diff line
@@ -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
+16 −10
Original line number Diff line number Diff line
@@ -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")
STEXI
@item -s
Wait gdb connection to port 1234 (@pxref{gdb_usage}).
DEF("gdb", HAS_ARG, QEMU_OPTION_gdb, \
    "-gdb dev        wait for gdb connection on 'dev'\n")
STEXI
@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, \
+8 −17
Original line number Diff line number Diff line
@@ -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,15 +5365,11 @@ 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);
    if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
        fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n",
                gdbstub_dev);
        exit(1);
    }
    }
#endif

    if (loadvm)