aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Michel <luc.michel@greensocs.com>2019-03-26 12:53:26 +0000
committerPeter Maydell <peter.maydell@linaro.org>2019-03-26 12:53:26 +0000
commitc99ef792dc9ec6d8a5061428faf396ea9ceb8f57 (patch)
tree4b086bca1c530b8336b97e6f2485d390d3789f8e
parentc8877d0f2f662bf01346a03bc9fd279954b4132d (diff)
gdbstub: fix vCont packet handling when no thread is specified
The vCont packet accepts a series of actions, each being applied on a given thread ID. Giving no thread ID for an action is valid and means "all threads". This commit fixes vCont packets being incorrectly rejected when no thread ID was given for an action. In multiprocess mode, the GDB Remote Protocol specification is unclear on what "all threads" means. We choose to apply the action on all threads of all attached processes. This commit is based on the initial fix by Lucien Murray-Pitts. Fixes: e40e5204af8388 Reported-by: Lucien Murray-Pitts <lucienmp_antispam@yahoo.com> Reported-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Luc Michel <luc.michel@greensocs.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20190325110452.6756-1-luc.michel@greensocs.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--gdbstub.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/gdbstub.c b/gdbstub.c
index bc774ae992..d54abd17cc 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1152,6 +1152,7 @@ static int gdb_handle_vcont(GDBState *s, const char *p)
uint32_t pid, tid;
GDBProcess *process;
CPUState *cpu;
+ GDBThreadIdKind kind;
#ifdef CONFIG_USER_ONLY
int max_cpus = 1; /* global variable max_cpus exists only in system mode */
@@ -1194,12 +1195,21 @@ static int gdb_handle_vcont(GDBState *s, const char *p)
goto out;
}
- if (*p++ != ':') {
+ if (*p == '\0' || *p == ';') {
+ /*
+ * No thread specifier, action is on "all threads". The
+ * specification is unclear regarding the process to act on. We
+ * choose all processes.
+ */
+ kind = GDB_ALL_PROCESSES;
+ } else if (*p++ == ':') {
+ kind = read_thread_id(p, &p, &pid, &tid);
+ } else {
res = -ENOTSUP;
goto out;
}
- switch (read_thread_id(p, &p, &pid, &tid)) {
+ switch (kind) {
case GDB_READ_THREAD_ERR:
res = -EINVAL;
goto out;