Same as gdb, minus the 'corrupt stack?' message.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- programs/winedbg/stack.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/programs/winedbg/stack.c b/programs/winedbg/stack.c index f49480a..519aa69 100644 --- a/programs/winedbg/stack.c +++ b/programs/winedbg/stack.c @@ -322,6 +322,15 @@ static void backtrace(void) dbg_curr_thread->curr_frame < dbg_curr_thread->num_frames; dbg_curr_thread->curr_frame++) { + if (dbg_curr_thread->curr_frame > 0 && + !memcmp(&dbg_curr_thread->frames[dbg_curr_thread->curr_frame].addr_frame, + &dbg_curr_thread->frames[dbg_curr_thread->curr_frame-1].addr_frame, + sizeof(ADDRESS64))) + { + dbg_printf("Backtrace stopped: previous frame identical to this frame\n"); + break; + } + dbg_printf("%s%d ", (cf == dbg_curr_thread->curr_frame ? "=>" : " "), dbg_curr_thread->curr_frame);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- programs/winedbg/gdbproxy.c | 71 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-)
diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c index 2561702..c02ad3b 100644 --- a/programs/winedbg/gdbproxy.c +++ b/programs/winedbg/gdbproxy.c @@ -214,6 +214,30 @@ struct cpu_register #define REG(r,gs,m) {FIELD_OFFSET(CONTEXT, r), sizeof(((CONTEXT*)NULL)->r), gs, m}
#ifdef __i386__ +typedef struct DECLSPEC_ALIGN(16) _M128A { + ULONGLONG Low; + LONGLONG High; +} M128A, *PM128A; + +typedef struct _XMM_SAVE_AREA32 { + WORD ControlWord; /* 000 */ + WORD StatusWord; /* 002 */ + BYTE TagWord; /* 004 */ + BYTE Reserved1; /* 005 */ + WORD ErrorOpcode; /* 006 */ + DWORD ErrorOffset; /* 008 */ + WORD ErrorSelector; /* 00c */ + WORD Reserved2; /* 00e */ + DWORD DataOffset; /* 010 */ + WORD DataSelector; /* 014 */ + WORD Reserved3; /* 016 */ + DWORD MxCsr; /* 018 */ + DWORD MxCsr_Mask; /* 01c */ + M128A FloatRegisters[8]; /* 020 */ + M128A XmmRegisters[16]; /* 0a0 */ + BYTE Reserved4[96]; /* 1a0 */ +} XMM_SAVE_AREA32, *PXMM_SAVE_AREA32; + static const char target_xml[] = ""; static struct cpu_register cpu_register_map[] = { REG(Eax, 4, CONTEXT_INTEGER), @@ -248,6 +272,15 @@ static struct cpu_register cpu_register_map[] = { { FIELD_OFFSET(CONTEXT, FloatSave.DataSelector), 2, 4, CONTEXT_FLOATING_POINT }, REG(FloatSave.DataOffset, 4, CONTEXT_FLOATING_POINT ), { FIELD_OFFSET(CONTEXT, FloatSave.ErrorSelector)+2, 2, 4, CONTEXT_FLOATING_POINT }, + { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[0]), 16, 16, CONTEXT_EXTENDED_REGISTERS }, + { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[1]), 16, 16, CONTEXT_EXTENDED_REGISTERS }, + { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[2]), 16, 16, CONTEXT_EXTENDED_REGISTERS }, + { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[3]), 16, 16, CONTEXT_EXTENDED_REGISTERS }, + { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[4]), 16, 16, CONTEXT_EXTENDED_REGISTERS }, + { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[5]), 16, 16, CONTEXT_EXTENDED_REGISTERS }, + { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[6]), 16, 16, CONTEXT_EXTENDED_REGISTERS }, + { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[7]), 16, 16, CONTEXT_EXTENDED_REGISTERS }, + { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, MxCsr), 4, 4, CONTEXT_EXTENDED_REGISTERS }, }; #elif defined(__powerpc__) static const char target_xml[] = ""; @@ -353,6 +386,39 @@ static struct cpu_register cpu_register_map[] = { REG(SegEs, 4, CONTEXT_SEGMENTS), REG(SegFs, 4, CONTEXT_SEGMENTS), REG(SegGs, 4, CONTEXT_SEGMENTS), + { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 0]), 10, 10, CONTEXT_FLOATING_POINT }, + { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 1]), 10, 10, CONTEXT_FLOATING_POINT }, + { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 2]), 10, 10, CONTEXT_FLOATING_POINT }, + { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 3]), 10, 10, CONTEXT_FLOATING_POINT }, + { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 4]), 10, 10, CONTEXT_FLOATING_POINT }, + { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 5]), 10, 10, CONTEXT_FLOATING_POINT }, + { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 6]), 10, 10, CONTEXT_FLOATING_POINT }, + { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 7]), 10, 10, CONTEXT_FLOATING_POINT }, + REG(u.FltSave.ControlWord, 4, CONTEXT_FLOATING_POINT), + REG(u.FltSave.StatusWord, 4, CONTEXT_FLOATING_POINT), + REG(u.FltSave.TagWord, 4, CONTEXT_FLOATING_POINT), + REG(u.FltSave.ErrorSelector, 4, CONTEXT_FLOATING_POINT), + REG(u.FltSave.ErrorOffset, 4, CONTEXT_FLOATING_POINT), + REG(u.FltSave.DataSelector, 4, CONTEXT_FLOATING_POINT), + REG(u.FltSave.DataOffset, 4, CONTEXT_FLOATING_POINT), + REG(u.FltSave.ErrorOpcode, 4, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm0, 16, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm1, 16, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm2, 16, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm3, 16, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm4, 16, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm5, 16, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm6, 16, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm7, 16, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm8, 16, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm9, 16, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm10, 16, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm11, 16, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm12, 16, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm13, 16, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm14, 16, CONTEXT_FLOATING_POINT), + REG(u.s.Xmm15, 16, CONTEXT_FLOATING_POINT), + REG(u.FltSave.MxCsr, 4, CONTEXT_FLOATING_POINT), }; #elif defined(__arm__) static const char target_xml[] = @@ -496,7 +562,7 @@ static BOOL fetch_context(struct gdb_context* gdbctx, HANDLE h, CONTEXT* ctx) { ctx->ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER -#if defined(__powerpc__) || defined(__i386__) +#if defined(__powerpc__) || defined(__i386__) || defined(__x86_64__) | CONTEXT_FLOATING_POINT #endif #ifdef CONTEXT_SEGMENTS @@ -505,6 +571,9 @@ static BOOL fetch_context(struct gdb_context* gdbctx, HANDLE h, CONTEXT* ctx) #ifdef CONTEXT_DEBUG_REGISTERS | CONTEXT_DEBUG_REGISTERS #endif +#ifdef CONTEXT_EXTENDED_REGISTERS + | CONTEXT_EXTENDED_REGISTERS +#endif ; if (!GetThreadContext(h, ctx)) {
Fixes bug #44349.
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.
Fix this problem by reporting the real bytes when they are requested, which is what gdb's native backend does as well.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- 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 c02ad3b..7b9a476 100644 --- a/programs/winedbg/gdbproxy.c +++ b/programs/winedbg/gdbproxy.c @@ -1568,6 +1568,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; @@ -1584,8 +1606,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);
Zebediah Figura z.figura12@gmail.com writes:
Same as gdb, minus the 'corrupt stack?' message.
This breaks backtraces through code that doesn't set the frame pointer. For instance, with the break removed:
=>0 0xf7f5adb9 __kernel_vsyscall+0x9() in [vdso].so (0x0033f5fc) Backtrace stopped: previous frame identical to this frame 1 0xf7b65082 gsignal+0xc1() in libc.so.6 (0x0033f5fc) 2 0xf7b66796 abort+0x1b5() in libc.so.6 (0xf7d08ce0) Backtrace stopped: previous frame identical to this frame 3 0xf7b5d11b in libc.so.6 (+0x2511a) (0xf7d08ce0) 4 0xf7b5d17b __assert_fail+0x3a() in libc.so.6 (0x0033f908) Backtrace stopped: previous frame identical to this frame 5 0x7e4cd97b error_handler+0x1ca(display=0x7c9fa700, error_evt=0x33f93c) [/home/julliard/wine/wine/dlls/winex11.drv/x11drv_main.c:283] in winex11 (0x0033f908) 6 0x7e30cb7a _XError+0x119() in libx11.so.6 (0x7e41db1c) 7 0x7e30977b in libx11.so.6 (+0x3977a) (0x0033f9e8) 8 0x7e30983f in libx11.so.6 (+0x3983e) (0x7c9fa700) Backtrace stopped: previous frame identical to this frame 9 0x7e30a866 _XReply+0x1b5() in libx11.so.6 (0x7c9fa700) Backtrace stopped: previous frame identical to this frame 10 0x7e305f7f XSync+0x4e() in libx11.so.6 (0x7c9fa700) Backtrace stopped: previous frame identical to this frame 11 0x7e30601a in libx11.so.6 (+0x36019) (0x7c9fa700) Backtrace stopped: previous frame identical to this frame 12 0x7e308627 XCreateWindow+0xc6() in libx11.so.6 (0x7c9fa700) 13 0x7e4b685a create_gl_drawable+0x159(hwnd=<is not available>, gl=0x15c3c8) [/home/julliard/wine/wine/dlls/winex11.drv/opengl.c:1378] in winex11 (0x0033fbc8)