mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-19 17:06:04 -07:00
dbghelp: Implement SymRefreshModuleList().
Signed-off-by: Eric Pouech <epouech@codeweavers.com>
This commit is contained in:
parent
00a6a7bc06
commit
ae50d75940
5 changed files with 40 additions and 31 deletions
|
@ -300,20 +300,6 @@ BOOL WINAPI SymGetSearchPath(HANDLE hProcess, PSTR szSearchPath,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* invade_process
|
||||
*
|
||||
* SymInitialize helper: loads in dbghelp all known (and loaded modules)
|
||||
* this assumes that hProcess is a handle on a valid process
|
||||
*/
|
||||
static BOOL WINAPI process_invade_cb(PCWSTR name, ULONG64 base, ULONG size, PVOID user)
|
||||
{
|
||||
HANDLE hProcess = user;
|
||||
|
||||
SymLoadModuleExW(hProcess, 0, name, NULL, base, size, NULL, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const WCHAR *process_getenv(const struct process *process, const WCHAR *name)
|
||||
{
|
||||
size_t name_len;
|
||||
|
@ -432,7 +418,10 @@ static BOOL check_live_target(struct process* pcs, BOOL wow64, BOOL child_wow64)
|
|||
|
||||
TRACE("got debug info address %#I64x from PEB %p\n", base, pbi.PebBaseAddress);
|
||||
if (!elf_read_wine_loader_dbg_info(pcs, base) && !macho_read_wine_loader_dbg_info(pcs, base))
|
||||
{
|
||||
WARN("couldn't load process debug info at %#I64x\n", base);
|
||||
pcs->loader = &empty_loader_ops;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -510,8 +499,9 @@ BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeP
|
|||
if (check_live_target(pcs, wow64, child_wow64))
|
||||
{
|
||||
if (fInvadeProcess)
|
||||
EnumerateLoadedModulesW64(hProcess, process_invade_cb, hProcess);
|
||||
if (pcs->loader) pcs->loader->synchronize_module_list(pcs);
|
||||
module_refresh_list(pcs);
|
||||
else
|
||||
pcs->loader->synchronize_module_list(pcs);
|
||||
}
|
||||
else if (fInvadeProcess)
|
||||
{
|
||||
|
|
|
@ -743,6 +743,7 @@ extern BOOL module_remove(struct process* pcs,
|
|||
extern void module_set_module(struct module* module, const WCHAR* name);
|
||||
extern WCHAR* get_wine_loader_name(struct process *pcs) __WINE_DEALLOC(HeapFree, 3) __WINE_MALLOC;
|
||||
extern BOOL module_is_wine_host(const WCHAR* module_name, const WCHAR* ext);
|
||||
extern BOOL module_refresh_list(struct process *pcs);
|
||||
|
||||
/* msc.c */
|
||||
extern BOOL pe_load_debug_directory(const struct process* pcs,
|
||||
|
|
|
@ -1785,7 +1785,6 @@ BOOL elf_read_wine_loader_dbg_info(struct process* pcs, ULONG_PTR addr)
|
|||
{
|
||||
ERR("Unable to access ELF libraries (outside 32bit limit)\n");
|
||||
module_remove(pcs, elf_info.module);
|
||||
pcs->loader = &empty_loader_ops;
|
||||
return FALSE;
|
||||
}
|
||||
TRACE("Found ELF debug header %#I64x\n", elf_info.dbg_hdr_addr);
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "dbghelp_private.h"
|
||||
#include "image_private.h"
|
||||
#include "psapi.h"
|
||||
|
@ -1317,7 +1319,11 @@ BOOL WINAPI EnumerateLoadedModulesW64(HANDLE process,
|
|||
size_t sysdir_len = 0, wowdir_len = 0;
|
||||
|
||||
/* process might not be a handle to a live process */
|
||||
if (!IsWow64Process2(process, &pcs_machine, &native_machine)) return FALSE;
|
||||
if (!IsWow64Process2(process, &pcs_machine, &native_machine))
|
||||
{
|
||||
SetLastError(STATUS_INVALID_CID);
|
||||
return FALSE;
|
||||
}
|
||||
with_32bit_modules = sizeof(void*) > sizeof(int) &&
|
||||
pcs_machine != IMAGE_FILE_MACHINE_UNKNOWN &&
|
||||
(dbghelp_options & SYMOPT_INCLUDE_32BIT_MODULES);
|
||||
|
@ -1600,18 +1606,41 @@ void module_reset_debug_info(struct module* module)
|
|||
module->sources = NULL;
|
||||
}
|
||||
|
||||
static BOOL WINAPI process_invade_cb(PCWSTR name, ULONG64 base, ULONG size, PVOID user)
|
||||
{
|
||||
HANDLE hProcess = user;
|
||||
|
||||
/* Note: this follows native behavior:
|
||||
* If a PE module has been unloaded from debuggee, it's not immediately removed
|
||||
* from module list in dbghelp.
|
||||
* Removal may eventually happen when loading a another module with SymLoadModule:
|
||||
* if the module to be loaded overlaps an existing one, SymLoadModule will
|
||||
* automatically unload the eldest one.
|
||||
*/
|
||||
SymLoadModuleExW(hProcess, 0, name, NULL, base, size, NULL, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL module_refresh_list(struct process *pcs)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
ret = pcs->loader->synchronize_module_list(pcs);
|
||||
ret = EnumerateLoadedModulesW64(pcs->handle, process_invade_cb, pcs->handle) && ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* SymRefreshModuleList (DBGHELP.@)
|
||||
*/
|
||||
BOOL WINAPI SymRefreshModuleList(HANDLE hProcess)
|
||||
{
|
||||
struct process* pcs;
|
||||
struct process *pcs;
|
||||
|
||||
TRACE("(%p)\n", hProcess);
|
||||
|
||||
if (!(pcs = process_find_by_handle(hProcess))) return FALSE;
|
||||
|
||||
return pcs->loader->synchronize_module_list(pcs);
|
||||
return module_refresh_list(pcs);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -537,7 +537,6 @@ static BOOL test_modules(void)
|
|||
|
||||
ret = SymRefreshModuleList(dummy);
|
||||
ok(!ret, "SymRefreshModuleList should have failed\n");
|
||||
todo_wine
|
||||
ok(GetLastError() == STATUS_INVALID_CID, "Unexpected last error %lx\n", GetLastError());
|
||||
|
||||
count = get_module_count(dummy);
|
||||
|
@ -875,7 +874,6 @@ static void test_loaded_modules(void)
|
|||
/* testing invalid process handle */
|
||||
ret = wrapper_EnumerateLoadedModulesW64((HANDLE)(ULONG_PTR)0xffffffc0, NULL, FALSE);
|
||||
ok(!ret, "EnumerateLoadedModulesW64 should have failed\n");
|
||||
todo_wine
|
||||
ok(GetLastError() == STATUS_INVALID_CID, "Unexpected last error %lx\n", GetLastError());
|
||||
|
||||
/* testing with child process of different machines */
|
||||
|
@ -939,7 +937,6 @@ static void test_loaded_modules(void)
|
|||
pcskind = get_process_kind(pi.hProcess);
|
||||
|
||||
ret = wrapper_SymRefreshModuleList(pi.hProcess);
|
||||
todo_wine_if(pcskind == PCSKIND_WOW64)
|
||||
ok(ret || broken(GetLastError() == STATUS_PARTIAL_COPY /* Win11 in some cases */ ||
|
||||
GetLastError() == STATUS_INFO_LENGTH_MISMATCH /* Win11 in some cases */),
|
||||
"SymRefreshModuleList failed: %lx\n", GetLastError());
|
||||
|
@ -1613,7 +1610,6 @@ static void test_refresh_modules(void)
|
|||
ok(ret, "SymRefreshModuleList failed: %lx\n", GetLastError());
|
||||
|
||||
count_current = get_module_count(GetCurrentProcess());
|
||||
todo_wine
|
||||
ok(count == count_current, "Unexpected module count %u, %u\n", count, count_current);
|
||||
|
||||
hmod = GetModuleHandleW(unused_dll);
|
||||
|
@ -1623,7 +1619,6 @@ static void test_refresh_modules(void)
|
|||
ok(hmod != NULL, "LoadLibraryW failed: %lu\n", GetLastError());
|
||||
|
||||
count_current = get_module_count(GetCurrentProcess());
|
||||
todo_wine
|
||||
ok(count == count_current, "Unexpected module count %u, %u\n", count, count_current);
|
||||
ret = is_module_present(GetCurrentProcess(), unused_dll);
|
||||
ok(!ret, "Couldn't find module %ls\n", unused_dll);
|
||||
|
@ -1632,17 +1627,14 @@ static void test_refresh_modules(void)
|
|||
ok(ret, "SymRefreshModuleList failed: %lx\n", GetLastError());
|
||||
|
||||
count_current = get_module_count(GetCurrentProcess());
|
||||
todo_wine
|
||||
ok(count + 1 == count_current, "Unexpected module count %u, %u\n", count, count_current);
|
||||
ret = is_module_present(GetCurrentProcess(), unused_dll);
|
||||
todo_wine
|
||||
ok(ret, "Couldn't find module %ls\n", unused_dll);
|
||||
|
||||
ret = FreeLibrary(hmod);
|
||||
ok(ret, "LoadLibraryW failed: %lu\n", GetLastError());
|
||||
|
||||
count_current = get_module_count(GetCurrentProcess());
|
||||
todo_wine
|
||||
ok(count + 1 == count_current, "Unexpected module count %u, %u\n", count, count_current);
|
||||
|
||||
ret = wrapper_SymRefreshModuleList(GetCurrentProcess());
|
||||
|
@ -1650,10 +1642,8 @@ static void test_refresh_modules(void)
|
|||
|
||||
/* SymRefreshModuleList() doesn't remove the unloaded modules... */
|
||||
count_current = get_module_count(GetCurrentProcess());
|
||||
todo_wine
|
||||
ok(count + 1 == count_current, "Unexpected module count %u != %u\n", count, count_current);
|
||||
ret = is_module_present(GetCurrentProcess(), unused_dll);
|
||||
todo_wine
|
||||
ok(ret, "Couldn't find module %ls\n", unused_dll);
|
||||
|
||||
ret = SymCleanup(GetCurrentProcess());
|
||||
|
|
Loading…
Reference in a new issue