This allows GDB to load symbols and resolve pending breakpoints for dynamically loaded DLLs.
Signed-off-by: Anton Baskanov baskanov@gmail.com --- programs/winedbg/gdbproxy.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c index b8a8a1da2f8..4fbb3cdff59 100644 --- a/programs/winedbg/gdbproxy.c +++ b/programs/winedbg/gdbproxy.c @@ -395,7 +395,7 @@ static BOOL handle_exception(struct gdb_context* gdbctx, EXCEPTION_DEBUG_INFO* e } }
-static BOOL handle_debug_event(struct gdb_context* gdbctx) +static BOOL handle_debug_event(struct gdb_context* gdbctx, BOOL stop_on_dll_load) { DEBUG_EVENT *de = &gdbctx->de; struct dbg_thread *thread; @@ -456,6 +456,8 @@ static BOOL handle_debug_event(struct gdb_context* gdbctx) de->u.LoadDll.nDebugInfoSize); dbg_load_module(gdbctx->process->handle, de->u.LoadDll.hFile, u.buffer, (DWORD_PTR)de->u.LoadDll.lpBaseOfDll, 0); + if (stop_on_dll_load) + break; return TRUE;
case UNLOAD_DLL_DEBUG_EVENT: @@ -463,6 +465,8 @@ static BOOL handle_debug_event(struct gdb_context* gdbctx) de->dwProcessId, de->dwThreadId, de->u.UnloadDll.lpBaseOfDll); SymUnloadModule(gdbctx->process->handle, (DWORD_PTR)de->u.UnloadDll.lpBaseOfDll); + if (stop_on_dll_load) + break; return TRUE;
case EXCEPTION_DEBUG_EVENT: @@ -596,7 +600,7 @@ static void wait_for_debuggee(struct gdb_context* gdbctx) break; } } - if (!handle_debug_event(gdbctx)) + if (!handle_debug_event(gdbctx, TRUE)) break; ContinueDebugEvent(gdbctx->de.dwProcessId, gdbctx->de.dwThreadId, DBG_CONTINUE); } @@ -916,6 +920,15 @@ static enum packet_return packet_reply_status(struct gdb_context* gdbctx) packet_reply_val(gdbctx, gdbctx->de.u.ExitProcess.dwExitCode, 4); packet_reply_close(gdbctx); return packet_done | packet_last_f; + + case LOAD_DLL_DEBUG_EVENT: + case UNLOAD_DLL_DEBUG_EVENT: + packet_reply_open(gdbctx); + packet_reply_add(gdbctx, "T"); + packet_reply_val(gdbctx, SIGTRAP, 1); + packet_reply_add(gdbctx, "library:;"); + packet_reply_close(gdbctx); + return packet_done; } }
@@ -2161,7 +2174,7 @@ static BOOL gdb_startup(struct gdb_context* gdbctx, unsigned flags, unsigned por goto cleanup;
/* step 2: do the process internal creation */ - handle_debug_event(gdbctx); + handle_debug_event(gdbctx, FALSE);
/* step 3: fire up gdb (if requested) */ if (flags & FLAG_NO_START) @@ -2250,7 +2263,7 @@ static BOOL gdb_init_context(struct gdb_context* gdbctx, unsigned flags, unsigne /* gdbctx->dwProcessId = pid; */ if (!gdb_startup(gdbctx, flags, port)) return FALSE; } - else if (!handle_debug_event(gdbctx)) + else if (!handle_debug_event(gdbctx, FALSE)) break; ContinueDebugEvent(gdbctx->de.dwProcessId, gdbctx->de.dwThreadId, DBG_CONTINUE); }
Le 11/07/2021 à 14:54, Anton Baskanov a écrit :
This allows GDB to load symbols and resolve pending breakpoints for dynamically loaded DLLs.
Hi
nothing critical, but is stop_on_dll_load usefull for DLL unload event ? it won't happen at startup, so my guess is that stop_on_dll_load is always TRUE for unload events!
and it would be consistent with the naming of the parameter <g>
my 2 cents
On понедельник, 12 июля 2021 г. 18:27:11 +07 you wrote:
Le 11/07/2021 à14:54, Anton Baskanov a écrità:
This allows GDB to load symbols and resolve pending breakpoints for dynamically loaded DLLs.
Hi
nothing critical, but is stop_on_dll_load usefull for DLL unload event ? it won't happen at startup, so my guess is that stop_on_dll_load is always TRUE for unload events!
and it would be consistent with the naming of the parameter <g>
my 2 cents
Hi Eric,
Thanks for the review. Actually, there is a DLL that is unloaded at startup: during kernelbase.dll initialization init_locale() calls GetDynamicTimeZoneInformation(), which calls RegLoadMUIStringW(), which loads and then unloads tzres.dll. I've renamed stop_on_dll_load to stop_on_dll_load_unload in v2.