dbghelp: Handle the case where loader isn't what WINELOADER reports.
use case, in a WoW setup: wine programs/winedbg/winedbg.exe.so notepad.exe where both winedbg and notepad are 64bit exec:s in this case, dbghelp (loaded from winedbg) reads '<...>/wine' from WINELOADER windows env block inside notepad (but the unix env block is correctly set to wine64 by the tweak in ntdll/unix/loader.c) as a consequence dbghelp doesn't get the ELF information (it tries to read 32bit ELF entities, and fails); hence misses all the loaded ELF libraries winedbg's command 'info share' only reports the PE modules note: the 'dual' case wine64 programs/winedbg/winedbg.exe.so c:\\windows\\syswow64\\notepad.exe where winedbg is a 64bit exec and notepad a 32bit shows the same failures workaround this in dbghelp by tweaking the value of WINELOADER whether the debuggee is 32 or 64bit Signed-off-by: Eric Pouech <eric.pouech@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ca00b056b8
commit
a4b206b384
|
@ -644,7 +644,7 @@ extern void module_reset_debug_info(struct module* module) DECLSPEC_HIDD
|
||||||
extern BOOL module_remove(struct process* pcs,
|
extern BOOL module_remove(struct process* pcs,
|
||||||
struct module* module) DECLSPEC_HIDDEN;
|
struct module* module) DECLSPEC_HIDDEN;
|
||||||
extern void module_set_module(struct module* module, const WCHAR* name) DECLSPEC_HIDDEN;
|
extern void module_set_module(struct module* module, const WCHAR* name) DECLSPEC_HIDDEN;
|
||||||
extern const WCHAR *get_wine_loader_name(struct process *pcs) DECLSPEC_HIDDEN;
|
extern WCHAR* get_wine_loader_name(struct process *pcs) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* msc.c */
|
/* msc.c */
|
||||||
extern BOOL pe_load_debug_directory(const struct process* pcs,
|
extern BOOL pe_load_debug_directory(const struct process* pcs,
|
||||||
|
|
|
@ -1752,10 +1752,16 @@ static const struct loader_ops elf_loader_ops =
|
||||||
BOOL elf_read_wine_loader_dbg_info(struct process* pcs, ULONG_PTR addr)
|
BOOL elf_read_wine_loader_dbg_info(struct process* pcs, ULONG_PTR addr)
|
||||||
{
|
{
|
||||||
struct elf_info elf_info;
|
struct elf_info elf_info;
|
||||||
BOOL ret;
|
BOOL ret = FALSE;
|
||||||
|
WCHAR* loader;
|
||||||
|
|
||||||
elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE;
|
elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE;
|
||||||
ret = elf_search_and_load_file(pcs, get_wine_loader_name(pcs), addr, 0, &elf_info);
|
loader = get_wine_loader_name(pcs);
|
||||||
|
if (loader)
|
||||||
|
{
|
||||||
|
ret = elf_search_and_load_file(pcs, loader, addr, 0, &elf_info);
|
||||||
|
HeapFree(GetProcessHeap(), 0, loader);
|
||||||
|
}
|
||||||
if (!ret || !elf_info.dbg_hdr_addr) return FALSE;
|
if (!ret || !elf_info.dbg_hdr_addr) return FALSE;
|
||||||
|
|
||||||
TRACE("Found ELF debug header %#lx\n", elf_info.dbg_hdr_addr);
|
TRACE("Found ELF debug header %#lx\n", elf_info.dbg_hdr_addr);
|
||||||
|
|
|
@ -1885,7 +1885,15 @@ static BOOL macho_search_loader(struct process* pcs, struct macho_info* macho_in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret) ret = macho_search_and_load_file(pcs, get_wine_loader_name(pcs), 0, macho_info);
|
if (!ret)
|
||||||
|
{
|
||||||
|
WCHAR* loader = get_wine_loader_name(pcs);
|
||||||
|
if (loader)
|
||||||
|
{
|
||||||
|
ret = macho_search_and_load_file(pcs, loader, 0, macho_info);
|
||||||
|
HeapFree(GetProcessHeap(), 0, loader);
|
||||||
|
}
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,12 +138,34 @@ void module_set_module(struct module* module, const WCHAR* name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returned string must be freed by caller */
|
/* Returned string must be freed by caller */
|
||||||
const WCHAR *get_wine_loader_name(struct process *pcs)
|
WCHAR *get_wine_loader_name(struct process *pcs)
|
||||||
{
|
{
|
||||||
const WCHAR *name = process_getenv(pcs, L"WINELOADER");
|
const WCHAR *name;
|
||||||
|
WCHAR* altname;
|
||||||
|
unsigned len;
|
||||||
|
|
||||||
|
name = process_getenv(pcs, L"WINELOADER");
|
||||||
if (!name) name = pcs->is_64bit ? L"wine64" : L"wine";
|
if (!name) name = pcs->is_64bit ? L"wine64" : L"wine";
|
||||||
TRACE("returning %s\n", debugstr_w(name));
|
len = lstrlenW(name);
|
||||||
return name;
|
|
||||||
|
/* WINELOADER isn't properly updated in Wow64 process calling inside Windows env block
|
||||||
|
* (it's updated in ELF env block though)
|
||||||
|
* So do the adaptation ourselves.
|
||||||
|
*/
|
||||||
|
altname = HeapAlloc(GetProcessHeap(), 0, (len + 2 + 1) * sizeof(WCHAR));
|
||||||
|
if (altname)
|
||||||
|
{
|
||||||
|
memcpy(altname, name, len * sizeof(WCHAR));
|
||||||
|
if (pcs->is_64bit && len >= 2 && memcmp(name + len - 2, L"64", 2 * sizeof(WCHAR)) != 0)
|
||||||
|
lstrcpyW(altname + len, L"64");
|
||||||
|
else if (!pcs->is_64bit && len >= 2 && !memcmp(name + len - 2, L"64", 2 * sizeof(WCHAR)))
|
||||||
|
altname[len - 2] = '\0';
|
||||||
|
else
|
||||||
|
altname[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("returning %s\n", debugstr_w(altname));
|
||||||
|
return altname;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* get_module_type(enum module_type type, BOOL virtual)
|
static const char* get_module_type(enum module_type type, BOOL virtual)
|
||||||
|
|
Loading…
Reference in New Issue