mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 15:53:54 -06:00
fix gdbstub support for multiple threads in usermode, v3
When debugging multi-threaded programs, QEMU's gdb stub would report the correct number of threads (the qfThreadInfo and qsThreadInfo packets). However, the stub was unable to actually switch between threads (the T packet), since it would report every thread except the first as being dead. Furthermore, the stub relied upon cpu_index as a reliable means of assigning IDs to the threads. This was a bad idea; if you have this sequence of events: initial thread created new thread #1 new thread #2 thread #1 exits new thread #3 thread #3 will have the same cpu_index as thread #1, which would confuse GDB. (This problem is partly due to the remote protocol not having a good way to send thread creation/destruction events.) We fix this by using the host thread ID for the identifier passed to GDB when debugging a multi-threaded userspace program. The thread ID might wrap, but the same sort of problems with wrapping thread IDs would come up with debugging programs natively, so this doesn't represent a problem. Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
This commit is contained in:
parent
4548eaea13
commit
1e9fa73016
4 changed files with 49 additions and 27 deletions
|
@ -3202,6 +3202,7 @@ static void *clone_func(void *arg)
|
|||
env = info->env;
|
||||
thread_env = env;
|
||||
info->tid = gettid();
|
||||
env->host_tid = info->tid;
|
||||
if (info->child_tidptr)
|
||||
put_user_u32(info->tid, info->child_tidptr);
|
||||
if (info->parent_tidptr)
|
||||
|
@ -3792,6 +3793,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
|||
/* FIXME: This probably breaks if a signal arrives. We should probably
|
||||
be disabling signals. */
|
||||
if (first_cpu->next_cpu) {
|
||||
TaskState *ts;
|
||||
CPUState **lastp;
|
||||
CPUState *p;
|
||||
|
||||
|
@ -3809,7 +3811,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
|||
/* Remove the CPU from the list. */
|
||||
*lastp = p->next_cpu;
|
||||
cpu_list_unlock();
|
||||
TaskState *ts = ((CPUState *)cpu_env)->opaque;
|
||||
ts = ((CPUState *)cpu_env)->opaque;
|
||||
if (ts->child_tidptr) {
|
||||
put_user_u32(0, ts->child_tidptr);
|
||||
sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue