Module: wine Branch: master Commit: 224b33c2be2ccab7ea5f2926f391717703b5427b URL: https://gitlab.winehq.org/wine/wine/-/commit/224b33c2be2ccab7ea5f2926f391717...
Author: Eric Pouech eric.pouech@gmail.com Date: Mon Jan 16 11:09:46 2023 -0600
winedbg: Track loaded modules.
Co-authored-by: Evan Tang etang@codeweavers.com
---
programs/winedbg/debugger.h | 12 ++++++++- programs/winedbg/tgt_active.c | 3 +-- programs/winedbg/types.c | 12 ++++----- programs/winedbg/winedbg.c | 61 ++++++++++++++++++++++++++++++++++++++----- 4 files changed, 72 insertions(+), 16 deletions(-)
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index c4c0402ef5f..2948b1ba437 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -246,6 +246,12 @@ struct dbg_thread BOOL suspended; };
+struct dbg_module +{ + struct list entry; + DWORD_PTR base; +}; + struct dbg_delayed_bp { BOOL is_symbol; @@ -271,6 +277,7 @@ struct dbg_process void* pio_data; const WCHAR* imageName; struct list threads; + struct list modules; struct backend_cpu* be_cpu; HANDLE event_on_first_exception; BOOL active_debuggee; @@ -503,7 +510,7 @@ extern BOOL types_is_integral_type(const struct dbg_lvalue*); extern BOOL types_is_float_type(const struct dbg_lvalue*); extern BOOL types_is_pointer_type(const struct dbg_lvalue*); extern BOOL types_find_basic(const WCHAR*, const char*, struct dbg_type* type); -extern BOOL types_unload_module(DWORD_PTR linear); +extern BOOL types_unload_module(struct dbg_process* pcs, DWORD_PTR linear);
/* winedbg.c */ #ifdef __GNUC__ @@ -524,6 +531,9 @@ extern struct dbg_thread* dbg_get_thread(struct dbg_process* p, DWORD tid); extern void dbg_del_thread(struct dbg_thread* t); extern BOOL dbg_init(HANDLE hProc, const WCHAR* in, BOOL invade); extern BOOL dbg_load_module(HANDLE hProc, HANDLE hFile, const WCHAR* name, DWORD_PTR base, DWORD size); +extern struct dbg_module* dbg_get_module(struct dbg_process* pcs, DWORD_PTR base); +extern void dbg_del_module(struct dbg_module* mod); +extern BOOL dbg_unload_module(struct dbg_process* pcs, DWORD_PTR base); extern void dbg_set_option(const char*, const char*); extern void dbg_start_interactive(const char*, HANDLE hFile); extern void dbg_init_console(void); diff --git a/programs/winedbg/tgt_active.c b/programs/winedbg/tgt_active.c index 9e130038f22..0d5ae754af5 100644 --- a/programs/winedbg/tgt_active.c +++ b/programs/winedbg/tgt_active.c @@ -501,8 +501,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de) de->dwProcessId, de->dwThreadId, de->u.UnloadDll.lpBaseOfDll); break_delete_xpoints_from_module((DWORD_PTR)de->u.UnloadDll.lpBaseOfDll); - types_unload_module((DWORD_PTR)de->u.UnloadDll.lpBaseOfDll); - SymUnloadModule64(dbg_curr_process->handle, (DWORD_PTR)de->u.UnloadDll.lpBaseOfDll); + dbg_unload_module(dbg_curr_process, (DWORD_PTR)de->u.UnloadDll.lpBaseOfDll); break;
case OUTPUT_DEBUG_STRING_EVENT: diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c index 5f5f1346c67..44872a7edad 100644 --- a/programs/winedbg/types.c +++ b/programs/winedbg/types.c @@ -1205,16 +1205,16 @@ BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, v return TRUE; }
-BOOL types_unload_module(DWORD_PTR linear) +BOOL types_unload_module(struct dbg_process* pcs, DWORD_PTR linear) { unsigned i; - if (!dbg_curr_process) return FALSE; - for (i = 0; i < dbg_curr_process->num_synthetized_types; i++) + if (!pcs) return FALSE; + for (i = 0; i < pcs->num_synthetized_types; i++) { - if (dbg_curr_process->synthetized_types[i].module == linear) + if (pcs->synthetized_types[i].module == linear) { - dbg_curr_process->synthetized_types[i].module = 0; - dbg_curr_process->synthetized_types[i].id = dbg_itype_none; + pcs->synthetized_types[i].module = 0; + pcs->synthetized_types[i].id = dbg_itype_none; } } return TRUE; diff --git a/programs/winedbg/winedbg.c b/programs/winedbg/winedbg.c index aa94f2f18ab..f5c573cf30e 100644 --- a/programs/winedbg/winedbg.c +++ b/programs/winedbg/winedbg.c @@ -273,6 +273,7 @@ struct dbg_process* dbg_add_process(const struct be_process_io* pio, DWORD pid, p->pio_data = NULL; p->imageName = NULL; list_init(&p->threads); + list_init(&p->modules); p->event_on_first_exception = NULL; p->active_debuggee = FALSE; p->next_bp = 1; /* breakpoint 0 is reserved for step-over */ @@ -316,11 +317,16 @@ void dbg_del_process(struct dbg_process* p) { struct dbg_thread* t; struct dbg_thread* t2; + struct dbg_module* mod; + struct dbg_module* mod2; int i;
LIST_FOR_EACH_ENTRY_SAFE(t, t2, &p->threads, struct dbg_thread, entry) dbg_del_thread(t);
+ LIST_FOR_EACH_ENTRY_SAFE(mod, mod2, &p->modules, struct dbg_module, entry) + dbg_del_module(mod); + for (i = 0; i < p->num_delayed_bp; i++) if (p->delayed_bp[i].is_symbol) free(p->delayed_bp[i].u.symbol.name); @@ -377,15 +383,56 @@ BOOL dbg_init(HANDLE hProc, const WCHAR* in, BOOL invade)
BOOL dbg_load_module(HANDLE hProc, HANDLE hFile, const WCHAR* name, DWORD_PTR base, DWORD size) { - BOOL ret = SymLoadModuleExW(hProc, hFile, name, NULL, base, size, NULL, 0); - if (ret) + struct dbg_process* pcs = dbg_get_process_h(hProc); + struct dbg_module* mod; + IMAGEHLP_MODULEW64 info; + + if (!pcs) return FALSE; + mod = malloc(sizeof(struct dbg_module)); + if (!mod) return FALSE; + if (!SymLoadModuleExW(hProc, hFile, name, NULL, base, size, NULL, 0)) { - IMAGEHLP_MODULEW64 ihm; - ihm.SizeOfStruct = sizeof(ihm); - if (SymGetModuleInfoW64(hProc, base, &ihm) && (ihm.PdbUnmatched || ihm.DbgUnmatched)) - dbg_printf("Loaded unmatched debug information for %s\n", wine_dbgstr_w(name)); + free(mod); + return FALSE; } - return ret; + mod->base = base; + list_add_head(&pcs->modules, &mod->entry); + + info.SizeOfStruct = sizeof(info); + if (SymGetModuleInfoW64(hProc, base, &info)) + if (info.PdbUnmatched || info.DbgUnmatched) + dbg_printf("Loaded unmatched debug information for %s\n", wine_dbgstr_w(name)); + + return TRUE; +} + +void dbg_del_module(struct dbg_module* mod) +{ + list_remove(&mod->entry); + free(mod); +} + +struct dbg_module* dbg_get_module(struct dbg_process* pcs, DWORD_PTR base) +{ + struct dbg_module* mod; + + if (!pcs) + return NULL; + LIST_FOR_EACH_ENTRY(mod, &pcs->modules, struct dbg_module, entry) + if (mod->base == base) + return mod; + return NULL; +} + +BOOL dbg_unload_module(struct dbg_process* pcs, DWORD_PTR base) +{ + struct dbg_module* mod = dbg_get_module(pcs, base); + + types_unload_module(pcs, base); + SymUnloadModule64(pcs->handle, base); + dbg_del_module(mod); + + return !!mod; }
struct dbg_thread* dbg_get_thread(struct dbg_process* p, DWORD tid)