This was using some conditional context read and dbg_curr_thread checks, which seems overcomplicated. Just read the context of the selected thread and write it back as needed.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- programs/winedbg/gdbproxy.c | 96 ++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 49 deletions(-)
diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c index 160c2df0d20..d0e0cfb3428 100644 --- a/programs/winedbg/gdbproxy.c +++ b/programs/winedbg/gdbproxy.c @@ -501,6 +501,7 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de) WCHAR buffer[256]; } u;
+ gdbctx->other_thread = NULL; dbg_curr_thread = dbg_get_thread(gdbctx->process, de->dwThreadId);
switch (de->dwDebugEventCode) @@ -941,16 +942,16 @@ static enum packet_return packet_reply_error(struct gdb_context* gdbctx, int err return packet_done; }
-static inline void packet_reply_register_hex_to(struct gdb_context* gdbctx, unsigned idx) +static inline void packet_reply_register_hex_to(struct gdb_context* gdbctx, dbg_ctx_t* ctx, unsigned idx) { const struct gdb_register *cpu_register_map = gdbctx->process->be_cpu->gdb_register_map;
if (cpu_register_map[idx].gdb_length == cpu_register_map[idx].ctx_length) - packet_reply_hex_to(gdbctx, cpu_register_ptr(gdbctx, &gdbctx->context, idx), + packet_reply_hex_to(gdbctx, cpu_register_ptr(gdbctx, ctx, idx), cpu_register_map[idx].gdb_length); else { - DWORD64 val = cpu_register(gdbctx, &gdbctx->context, idx); + DWORD64 val = cpu_register(gdbctx, ctx, idx); unsigned i;
for (i = 0; i < cpu_register_map[idx].gdb_length; i++) @@ -969,11 +970,18 @@ static inline void packet_reply_register_hex_to(struct gdb_context* gdbctx, unsi
static enum packet_return packet_reply_status(struct gdb_context* gdbctx) { - if (gdbctx->process != NULL) + struct dbg_process *proc = gdbctx->process; + dbg_ctx_t ctx; + + if (proc != NULL) { + struct backend_cpu *be = proc->be_cpu; unsigned char sig; unsigned i;
+ if (!be->get_context(dbg_curr_thread->handle, &ctx)) + return packet_error; + packet_reply_open(gdbctx); packet_reply_add(gdbctx, "T"); sig = gdbctx->last_sig; @@ -982,14 +990,11 @@ static enum packet_return packet_reply_status(struct gdb_context* gdbctx) packet_reply_val(gdbctx, dbg_curr_thread->tid, 4); packet_reply_add(gdbctx, ";");
- for (i = 0; i < gdbctx->process->be_cpu->gdb_num_regs; i++) + for (i = 0; i < be->gdb_num_regs; i++) { - /* FIXME: this call will also grow the buffer... - * unneeded, but not harmful - */ packet_reply_val(gdbctx, i, 1); packet_reply_add(gdbctx, ":"); - packet_reply_register_hex_to(gdbctx, i); + packet_reply_register_hex_to(gdbctx, &ctx, i); packet_reply_add(gdbctx, ";"); }
@@ -1251,20 +1256,18 @@ 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 backend_cpu *be = thrd->process->be_cpu; int i; dbg_ctx_t ctx;
assert(gdbctx->in_trap); - - if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread) - { - if (!fetch_context(gdbctx, gdbctx->other_thread->handle, &ctx)) - return packet_error; - } + if (!thrd || !be->get_context(thrd->handle, &ctx)) + return packet_error;
packet_reply_open(gdbctx); - for (i = 0; i < gdbctx->process->be_cpu->gdb_num_regs; i++) - packet_reply_register_hex_to(gdbctx, i); + for (i = 0; i < be->gdb_num_regs; i++) + packet_reply_register_hex_to(gdbctx, &ctx, i);
packet_reply_close(gdbctx); return packet_done; @@ -1272,31 +1275,30 @@ static enum packet_return packet_read_registers(struct gdb_context* gdbctx)
static enum packet_return packet_write_registers(struct gdb_context* gdbctx) { - const size_t cpu_num_regs = gdbctx->process->be_cpu->gdb_num_regs; + struct dbg_thread *thrd = gdbctx->other_thread ? gdbctx->other_thread : dbg_curr_thread; + struct backend_cpu *be = thrd->process->be_cpu; + const size_t cpu_num_regs = be->gdb_num_regs; unsigned i; dbg_ctx_t ctx; - dbg_ctx_t *pctx = &gdbctx->context; const char* ptr;
assert(gdbctx->in_trap); - if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread) - { - if (!fetch_context(gdbctx, gdbctx->other_thread->handle, pctx = &ctx)) - return packet_error; - } - if (gdbctx->in_packet_len < cpu_num_regs * 2) return packet_error; + if (!thrd || !be->get_context(thrd->handle, &ctx)) + return packet_error; + if (gdbctx->in_packet_len < cpu_num_regs * 2) + return packet_error;
ptr = gdbctx->in_packet; for (i = 0; i < cpu_num_regs; i++) - cpu_register_hex_from(gdbctx, pctx, i, &ptr); + cpu_register_hex_from(gdbctx, &ctx, i, &ptr);
- if (pctx != &gdbctx->context && - !gdbctx->process->be_cpu->set_context(gdbctx->other_thread->handle, pctx)) + if (!be->set_context(thrd->handle, &ctx)) { ERR("Failed to set context for tid %04x, error %u\n", - gdbctx->other_thread->tid, GetLastError()); + thrd->tid, GetLastError()); return packet_error; } + return packet_ok; }
@@ -1414,42 +1416,42 @@ 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 backend_cpu *be = thrd->process->be_cpu; unsigned reg; dbg_ctx_t ctx; - dbg_ctx_t *pctx = &gdbctx->context;
assert(gdbctx->in_trap); reg = hex_to_int(gdbctx->in_packet, gdbctx->in_packet_len); - if (reg >= gdbctx->process->be_cpu->gdb_num_regs) + if (reg >= be->gdb_num_regs) { WARN("Unhandled register %u\n", reg); return packet_error; } - if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread) - { - if (!fetch_context(gdbctx, gdbctx->other_thread->handle, pctx = &ctx)) - return packet_error; - }
- TRACE("%u => %s\n", reg, wine_dbgstr_longlong(cpu_register(gdbctx, pctx, reg))); + if (!thrd || !be->get_context(thrd->handle, &ctx)) + return packet_error; + + TRACE("%u => %s\n", reg, wine_dbgstr_longlong(cpu_register(gdbctx, &ctx, reg)));
packet_reply_open(gdbctx); - packet_reply_register_hex_to(gdbctx, reg); + packet_reply_register_hex_to(gdbctx, &ctx, reg); packet_reply_close(gdbctx); return packet_done; }
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 backend_cpu *be = thrd->process->be_cpu; unsigned reg; char* ptr; dbg_ctx_t ctx; - dbg_ctx_t *pctx = &gdbctx->context;
assert(gdbctx->in_trap);
reg = strtoul(gdbctx->in_packet, &ptr, 16); - if (ptr == NULL || reg >= gdbctx->process->be_cpu->gdb_num_regs || *ptr++ != '=') + if (ptr == NULL || reg >= be->gdb_num_regs || *ptr++ != '=') { WARN("Unhandled register %s\n", debugstr_an(gdbctx->in_packet, gdbctx->in_packet_len)); @@ -1462,18 +1464,14 @@ static enum packet_return packet_write_register(struct gdb_context* gdbctx) TRACE("%u <= %s\n", reg, debugstr_an(ptr, (int)(gdbctx->in_packet_len - (ptr - gdbctx->in_packet))));
- if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread) - { - if (!fetch_context(gdbctx, gdbctx->other_thread->handle, pctx = &ctx)) - return packet_error; - } + if (!thrd || !be->get_context(thrd->handle, &ctx)) + return packet_error;
- cpu_register_hex_from(gdbctx, pctx, reg, (const char**)&ptr); - if (pctx != &gdbctx->context && - !gdbctx->process->be_cpu->set_context(gdbctx->other_thread->handle, pctx)) + cpu_register_hex_from(gdbctx, &ctx, reg, (const char**)&ptr); + if (!be->set_context(thrd->handle, &ctx)) { ERR("Failed to set context for tid %04x, error %u\n", - gdbctx->other_thread->tid, GetLastError()); + thrd->tid, GetLastError()); return packet_error; }