Eric Pouech : dbghelp: Handle the case where loader isn't what WINELOADER reports.

Alexandre Julliard julliard at winehq.org
Fri Sep 3 16:25:28 CDT 2021


Module: wine
Branch: master
Commit: a4b206b384c9367d0add95d5a0c0bd84374f6cb9
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=a4b206b384c9367d0add95d5a0c0bd84374f6cb9

Author: Eric Pouech <eric.pouech at gmail.com>
Date:   Fri Sep  3 08:57:12 2021 +0200

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 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dbghelp/dbghelp_private.h |  2 +-
 dlls/dbghelp/elf_module.c      | 10 ++++++++--
 dlls/dbghelp/macho_module.c    | 10 +++++++++-
 dlls/dbghelp/module.c          | 30 ++++++++++++++++++++++++++----
 4 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index eb2b53e947a..d6280a5189b 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -644,7 +644,7 @@ extern void         module_reset_debug_info(struct module* module) DECLSPEC_HIDD
 extern BOOL         module_remove(struct process* pcs,
                                   struct module* module) 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 */
 extern BOOL         pe_load_debug_directory(const struct process* pcs,
diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c
index d1a4454e043..7be7e8efce6 100644
--- a/dlls/dbghelp/elf_module.c
+++ b/dlls/dbghelp/elf_module.c
@@ -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)
 {
     struct elf_info     elf_info;
-    BOOL ret;
+    BOOL ret = FALSE;
+    WCHAR* loader;
 
     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;
 
     TRACE("Found ELF debug header %#lx\n", elf_info.dbg_hdr_addr);
diff --git a/dlls/dbghelp/macho_module.c b/dlls/dbghelp/macho_module.c
index 602f7e45c14..7b0b80c4900 100644
--- a/dlls/dbghelp/macho_module.c
+++ b/dlls/dbghelp/macho_module.c
@@ -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;
 }
 
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c
index c278a627d37..3bc2a9e143a 100644
--- a/dlls/dbghelp/module.c
+++ b/dlls/dbghelp/module.c
@@ -138,12 +138,34 @@ void module_set_module(struct module* module, const WCHAR* name)
 }
 
 /* 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";
-    TRACE("returning %s\n", debugstr_w(name));
-    return name;
+    len = lstrlenW(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)




More information about the wine-cvs mailing list