Commit dd32aa10476d04853b71657d5345e812915d87ed
Committed by
Anthony Liguori
1 parent
8389e7f4
gdbstub: Add vCont support
This patch adds support for the vCont remote gdb command. It is used by gdb 6.8 or better to switch the debugging focus for single-stepping multi-threaded targets, ie. multi-threaded application in user mode emulation or VCPUs in system emulation. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing
1 changed file
with
58 additions
and
0 deletions
gdbstub.c
... | ... | @@ -1631,6 +1631,64 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) |
1631 | 1631 | s->signal = 0; |
1632 | 1632 | gdb_continue(s); |
1633 | 1633 | return RS_IDLE; |
1634 | + case 'v': | |
1635 | + if (strncmp(p, "Cont", 4) == 0) { | |
1636 | + int res_signal, res_thread; | |
1637 | + | |
1638 | + p += 4; | |
1639 | + if (*p == '?') { | |
1640 | + put_packet(s, "vCont;c;C;s;S"); | |
1641 | + break; | |
1642 | + } | |
1643 | + res = 0; | |
1644 | + res_signal = 0; | |
1645 | + res_thread = 0; | |
1646 | + while (*p) { | |
1647 | + int action, signal; | |
1648 | + | |
1649 | + if (*p++ != ';') { | |
1650 | + res = 0; | |
1651 | + break; | |
1652 | + } | |
1653 | + action = *p++; | |
1654 | + signal = 0; | |
1655 | + if (action == 'C' || action == 'S') { | |
1656 | + signal = strtoul(p, (char **)&p, 16); | |
1657 | + } else if (action != 'c' && action != 's') { | |
1658 | + res = 0; | |
1659 | + break; | |
1660 | + } | |
1661 | + thread = 0; | |
1662 | + if (*p == ':') { | |
1663 | + thread = strtoull(p+1, (char **)&p, 16); | |
1664 | + } | |
1665 | + action = tolower(action); | |
1666 | + if (res == 0 || (res == 'c' && action == 's')) { | |
1667 | + res = action; | |
1668 | + res_signal = signal; | |
1669 | + res_thread = thread; | |
1670 | + } | |
1671 | + } | |
1672 | + if (res) { | |
1673 | + if (res_thread != -1 && res_thread != 0) { | |
1674 | + env = find_cpu(res_thread); | |
1675 | + if (env == NULL) { | |
1676 | + put_packet(s, "E22"); | |
1677 | + break; | |
1678 | + } | |
1679 | + s->c_cpu = env; | |
1680 | + } | |
1681 | + if (res == 's') { | |
1682 | + cpu_single_step(s->c_cpu, sstep_flags); | |
1683 | + } | |
1684 | + s->signal = res_signal; | |
1685 | + gdb_continue(s); | |
1686 | + return RS_IDLE; | |
1687 | + } | |
1688 | + break; | |
1689 | + } else { | |
1690 | + goto unknown_command; | |
1691 | + } | |
1634 | 1692 | case 'k': |
1635 | 1693 | /* Kill the target */ |
1636 | 1694 | fprintf(stderr, "\nQEMU: Terminated via GDBstub\n"); | ... | ... |