winedbg: Track loaded modules.

Co-authored-by: Evan Tang <etang@codeweavers.com>
This commit is contained in:
Eric Pouech 2023-01-16 11:09:46 -06:00 committed by Alexandre Julliard
parent 0f6dcbbb2c
commit 224b33c2be
4 changed files with 72 additions and 16 deletions

View file

@ -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);

View file

@ -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:

View file

@ -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;

View file

@ -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)