[PATCH 15/15] winedbg: Use tid for other/exec thread operations.
Rémi Bernon
rbernon at codeweavers.com
Mon Jan 27 06:07:18 CST 2020
Looking up the thread makes us loose track of any/all (0/-1) tids, we
need that for correct continue/step implementation.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
programs/winedbg/gdbproxy.c | 73 ++++++++++++++++++++-----------------
1 file changed, 39 insertions(+), 34 deletions(-)
diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c
index e53ba2b965d..ccb33e870fd 100644
--- a/programs/winedbg/gdbproxy.c
+++ b/programs/winedbg/gdbproxy.c
@@ -84,8 +84,8 @@ struct gdb_context
int out_len;
int out_curr_packet;
/* generic GDB thread information */
- struct dbg_thread* exec_thread; /* thread used in step & continue */
- struct dbg_thread* other_thread; /* thread to be used in any other operation */
+ int exec_tid; /* tid used in step & continue */
+ int other_tid; /* tid to be used in any other operation */
/* current Win32 trap env */
unsigned last_sig;
BOOL in_trap;
@@ -504,10 +504,13 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
WCHAR buffer[256];
} u;
- gdbctx->exec_thread = NULL;
- gdbctx->other_thread = NULL;
dbg_curr_thread = dbg_get_thread(gdbctx->process, de->dwThreadId);
- if (dbg_curr_thread) dbg_curr_thread->continue_mode = DBG_REPLY_LATER;
+ if (dbg_curr_thread)
+ {
+ dbg_curr_thread->continue_mode = DBG_REPLY_LATER;
+ gdbctx->exec_tid = dbg_curr_thread->tid;
+ gdbctx->other_tid = dbg_curr_thread->tid;
+ }
switch (de->dwDebugEventCode)
{
@@ -593,8 +596,6 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
de->dwProcessId, de->dwThreadId, de->u.ExitThread.dwExitCode);
assert(dbg_curr_thread);
- if (dbg_curr_thread == gdbctx->exec_thread) gdbctx->exec_thread = NULL;
- if (dbg_curr_thread == gdbctx->other_thread) gdbctx->other_thread = NULL;
dbg_del_thread(dbg_curr_thread);
break;
@@ -735,6 +736,19 @@ static void handle_step_or_continue(struct gdb_context* gdbctx, int tid, BOOL st
}
}
+static struct dbg_thread* thread_from_tid(struct gdb_context* gdbctx, int tid)
+{
+ struct dbg_process *proc = gdbctx->process;
+ struct dbg_thread *thrd;
+
+ LIST_FOR_EACH_ENTRY(thrd, &proc->threads, struct dbg_thread, entry)
+ {
+ if (tid > 0 && thrd->tid != tid) continue;
+ return thrd;
+ }
+ return dbg_curr_thread;
+}
+
static void detach_debuggee(struct gdb_context* gdbctx, BOOL kill)
{
handle_step_or_continue(gdbctx, -1, FALSE, -1);
@@ -1050,7 +1064,7 @@ static enum packet_return packet_continue(struct gdb_context* gdbctx)
if (snscanf(gdbctx->in_packet, gdbctx->in_packet_len, "%p", &addr) == 1)
FIXME("Continue at address %p not supported\n", addr);
- handle_step_or_continue(gdbctx, gdbctx->exec_thread ? gdbctx->exec_thread->tid : -1, FALSE, -1);
+ handle_step_or_continue(gdbctx, gdbctx->exec_tid, FALSE, -1);
wait_for_debuggee(gdbctx);
return packet_reply_status(gdbctx);
@@ -1127,7 +1141,7 @@ static enum packet_return packet_continue_signal(struct gdb_context* gdbctx)
if (sig != gdbctx->last_sig)
return packet_error;
- handle_step_or_continue(gdbctx, gdbctx->exec_thread ? gdbctx->exec_thread->tid : -1, FALSE, sig);
+ handle_step_or_continue(gdbctx, gdbctx->exec_tid, FALSE, sig);
wait_for_debuggee(gdbctx);
return packet_reply_status(gdbctx);
@@ -1141,7 +1155,7 @@ static enum packet_return packet_detach(struct gdb_context* gdbctx)
static enum packet_return packet_read_registers(struct gdb_context* gdbctx)
{
- struct dbg_thread *thrd = gdbctx->other_thread ? gdbctx->other_thread : dbg_curr_thread;
+ struct dbg_thread *thrd = thread_from_tid(gdbctx, gdbctx->other_tid);
struct backend_cpu *be = thrd->process->be_cpu;
int i;
dbg_ctx_t ctx;
@@ -1160,7 +1174,7 @@ static enum packet_return packet_read_registers(struct gdb_context* gdbctx)
static enum packet_return packet_write_registers(struct gdb_context* gdbctx)
{
- struct dbg_thread *thrd = gdbctx->other_thread ? gdbctx->other_thread : dbg_curr_thread;
+ struct dbg_thread *thrd = thread_from_tid(gdbctx, gdbctx->other_tid);
struct backend_cpu *be = thrd->process->be_cpu;
const size_t cpu_num_regs = be->gdb_num_regs;
unsigned i;
@@ -1199,28 +1213,18 @@ static enum packet_return packet_kill(struct gdb_context* gdbctx)
static enum packet_return packet_thread(struct gdb_context* gdbctx)
{
- char* end;
- unsigned thread;
-
switch (gdbctx->in_packet[0])
{
case 'c':
+ if (snscanf(gdbctx->in_packet, gdbctx->in_packet_len, "c%x", &gdbctx->exec_tid) == 1)
+ return packet_ok;
+ gdbctx->exec_tid = -1;
+ return packet_error;
case 'g':
- if (gdbctx->in_packet[1] == '-')
- thread = -strtol(gdbctx->in_packet + 2, &end, 16);
- else
- thread = strtol(gdbctx->in_packet + 1, &end, 16);
- if (end == NULL || end > gdbctx->in_packet + gdbctx->in_packet_len)
- {
- ERR("Failed to parse %s\n",
- debugstr_an(gdbctx->in_packet, gdbctx->in_packet_len));
- return packet_error;
- }
- if (gdbctx->in_packet[0] == 'c')
- gdbctx->exec_thread = dbg_get_thread(gdbctx->process, thread);
- else
- gdbctx->other_thread = dbg_get_thread(gdbctx->process, thread);
- return packet_ok;
+ if (snscanf(gdbctx->in_packet, gdbctx->in_packet_len, "g%x", &gdbctx->other_tid) == 1)
+ return packet_ok;
+ gdbctx->other_tid = -1;
+ return packet_error;
default:
FIXME("Unknown thread sub-command %c\n", gdbctx->in_packet[0]);
return packet_error;
@@ -1301,7 +1305,7 @@ static enum packet_return packet_write_memory(struct gdb_context* gdbctx)
static enum packet_return packet_read_register(struct gdb_context* gdbctx)
{
- struct dbg_thread *thrd = gdbctx->other_thread ? gdbctx->other_thread : dbg_curr_thread;
+ struct dbg_thread *thrd = thread_from_tid(gdbctx, gdbctx->other_tid);
struct backend_cpu *be = thrd->process->be_cpu;
unsigned reg;
dbg_ctx_t ctx;
@@ -1327,7 +1331,7 @@ static enum packet_return packet_read_register(struct gdb_context* gdbctx)
static enum packet_return packet_write_register(struct gdb_context* gdbctx)
{
- struct dbg_thread *thrd = gdbctx->other_thread ? gdbctx->other_thread : dbg_curr_thread;
+ struct dbg_thread *thrd = thread_from_tid(gdbctx, gdbctx->other_tid);
struct backend_cpu *be = thrd->process->be_cpu;
unsigned reg;
char* ptr;
@@ -1795,7 +1799,7 @@ static enum packet_return packet_step(struct gdb_context* gdbctx)
if (snscanf(gdbctx->in_packet, gdbctx->in_packet_len, "%p", &addr) == 1)
FIXME("Continue at address %p not supported\n", addr);
- handle_step_or_continue(gdbctx, gdbctx->exec_thread ? gdbctx->exec_thread->tid : -1, TRUE, -1);
+ handle_step_or_continue(gdbctx, gdbctx->exec_tid, TRUE, -1);
wait_for_debuggee(gdbctx);
return packet_reply_status(gdbctx);
@@ -1812,7 +1816,7 @@ static enum packet_return packet_step_signal(struct gdb_context* gdbctx)
if (sig != gdbctx->last_sig)
return packet_error;
- handle_step_or_continue(gdbctx, gdbctx->exec_thread ? gdbctx->exec_thread->tid : -1, TRUE, sig);
+ handle_step_or_continue(gdbctx, gdbctx->exec_tid, TRUE, sig);
wait_for_debuggee(gdbctx);
return packet_reply_status(gdbctx);
@@ -2114,7 +2118,8 @@ static BOOL gdb_init_context(struct gdb_context* gdbctx, unsigned flags, unsigne
gdbctx->out_len = 0;
gdbctx->out_curr_packet = -1;
- gdbctx->exec_thread = gdbctx->other_thread = NULL;
+ gdbctx->exec_tid = -1;
+ gdbctx->other_tid = -1;
gdbctx->last_sig = 0;
gdbctx->in_trap = FALSE;
gdbctx->process = NULL;
--
2.25.0
More information about the wine-devel
mailing list