forked from auracaster/openocd
rtos: server/gdb_server: fix missing thread ID in stop reply
Cherry-picked from [1]. To replicate the issue that this fixes: 1. Connect to a multi-hart RISC-V target configured as an SMP group. 2. Start a GDB instance against the running OpenOCD. 3. Observe that GDB might display "warning: multi-threaded target stopped without sending a thread-id, using first non-exited thread." 4. Set a breakpoint in code that any non-hart-0 hart is expected to reach (but hart 0 is not expected to reach). 5. Allow a non-hart-0 hart to reach the breakpoint. 6. Remove the breakpoint. 7. Do a few sequential `stepi` commands in GDB. 8. Observe that GDB displays "Switching to Thread 1" even though the thread that was just single stepped was not Thread 1 in GDB. Also observe that the register values in GDB correspond to the thread that was single-stepped, not Thread 1. Basically GDB erroneously starts to consider thread 1 to be current, when in fact the thread that was single-stepped is still current. The changes in this pull request are intended to avoid the erroneous "Switching to Thread 1" described in (8) above. What was happening was that, in a couple areas of code, non-hart-0 harts weren't seen as belonging to an RTOS module, and this had the effect of (1) bypassing `hwthread_update_threads()` being called after a halt; (2) omitting a thread ID in a stop reply over GDB remote protocol connection (requiring GDB to take an arbitrary guess of current thread id, a guess that is wrong unless the current thread happens to be hart 0). Link: https://github.com/riscv-collab/riscv-openocd/pull/675 [1] Change-Id: I9872062dfa0e3f1ca531d282d52a1b04c527546a Signed-off-by: Greg Savin <greg.savin@sifive.com> Reviewed-on: https://review.openocd.org/c/openocd/+/9183 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
This commit is contained in:
@@ -813,9 +813,12 @@ static void gdb_signal_reply(struct target *target, struct connection *connectio
|
||||
sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "W00");
|
||||
} else {
|
||||
struct target *ct;
|
||||
if (target->rtos) {
|
||||
target->rtos->current_threadid = target->rtos->current_thread;
|
||||
target->rtos->gdb_target_for_threadid(connection, target->rtos->current_threadid, &ct);
|
||||
struct rtos *rtos;
|
||||
|
||||
rtos = rtos_from_target(target);
|
||||
if (rtos) {
|
||||
rtos->current_threadid = rtos->current_thread;
|
||||
rtos->gdb_target_for_threadid(connection, rtos->current_threadid, &ct);
|
||||
} else {
|
||||
ct = target;
|
||||
}
|
||||
@@ -853,9 +856,9 @@ static void gdb_signal_reply(struct target *target, struct connection *connectio
|
||||
}
|
||||
|
||||
current_thread[0] = '\0';
|
||||
if (target->rtos)
|
||||
if (rtos)
|
||||
snprintf(current_thread, sizeof(current_thread), "thread:%" PRIx64 ";",
|
||||
target->rtos->current_thread);
|
||||
rtos->current_thread);
|
||||
|
||||
sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "T%2.2x%s%s",
|
||||
signal_var, stop_reason, current_thread);
|
||||
|
||||
Reference in New Issue
Block a user