Module: wine Branch: oldstable Commit: e46cfd0fbec434a7258f56c7780016f6b3123567 URL: https://source.winehq.org/git/wine.git/?a=commit;h=e46cfd0fbec434a7258f56c77...
Author: Zebediah Figura z.figura12@gmail.com Date: Sun Jan 14 19:01:15 2018 -0600
winedbg/gdbproxy: Replace memory read over a breakpoint with the real value.
Normally, when we hit a breakpoint, we remove it before stopping and add it after continuing. gdb, however, reads the process memory before requesting that the breakpoint be removed, and apparently caches it until the `stepi` instruction is executed; as a result, it thinks that the interrupt byte that is present in the code is an actual interrupt and not a breakpoint, and so tries to step over it as one byte instead of executing the real instruction at that location.
Signed-off-by: Zebediah Figura z.figura12@gmail.com Signed-off-by: Alexandre Julliard julliard@winehq.org (cherry picked from commit eb63a5f3c3c1851f212bd14f91da329bf3166e42) Signed-off-by: Michael Stefaniuc mstefani@winehq.org
---
programs/winedbg/gdbproxy.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c index f94fef5..400f6de 100644 --- a/programs/winedbg/gdbproxy.c +++ b/programs/winedbg/gdbproxy.c @@ -1499,6 +1499,28 @@ static enum packet_return packet_thread(struct gdb_context* gdbctx) } }
+static BOOL read_memory(struct gdb_context *gdbctx, char *addr, char *buffer, SIZE_T blk_len, SIZE_T *r) +{ + /* Wrapper around process_io->read() that replaces values displaced by breakpoints. */ + + BOOL ret; + + ret = gdbctx->process->process_io->read(gdbctx->process->handle, addr, buffer, blk_len, r); + if (ret) + { + struct gdb_ctx_Xpoint *xpt; + + for (xpt = &gdbctx->Xpoints[NUM_XPOINT - 1]; xpt >= gdbctx->Xpoints; xpt--) + { + char *xpt_addr = xpt->addr; + + if (xpt->type != -1 && xpt_addr >= addr && xpt_addr < addr + blk_len) + buffer[xpt_addr - addr] = xpt->val; + } + } + return ret; +} + static enum packet_return packet_read_memory(struct gdb_context* gdbctx) { char *addr; @@ -1515,8 +1537,7 @@ static enum packet_return packet_read_memory(struct gdb_context* gdbctx) for (nread = 0; nread < len; nread += r, addr += r) { blk_len = min(sizeof(buffer), len - nread); - if (!gdbctx->process->process_io->read(gdbctx->process->handle, addr, buffer, blk_len, &r) || - r == 0) + if (!read_memory(gdbctx, addr, buffer, blk_len, &r) || r == 0) { /* fail at first address, return error */ if (nread == 0) return packet_reply_error(gdbctx, EFAULT);