[PATCH v2 1/1] dlls/dbghelp: introduce symt_find_symbol_at()

Eric Pouech wine at gitlab.winehq.org
Fri Apr 29 05:11:36 CDT 2022


From: Eric Pouech <eric.pouech at gmail.com>

To be used in place of symt_find_nearest().
symt_find_symbol_at() ensures that the address passed is within the
boundaries of the returned symbol (while find_nearest() doesn't).

This fixes erroneous backtraces in debugger like:
$ ./wine winedbg notepad
WineDbg starting on pid 0104
RtlDefaultNpAcl () at Z:\home\eric\work\wine\dlls\ntdll\sec.c:1731
0x00000170054805 ntdll+0x54805 [Z:\home\eric\work\wine\dlls\ntdll\sec.c:1731]: ret
1731    }
Wine-dbg>bt
Backtrace:
=>0 0x00000170054805 RtlDefaultNpAcl+0x2d5(pAcl=<internal error>) [Z:\home\eric\work\wine\dlls\ntdll\sec.c:1731] in ntdll (0x000001700701a4)
  1 0x0000017002d6c4 __wine_pop_frame(pAcl=<internal error>) [Z:\home\eric\work\wine\include\wine\exception.h:273] in ntdll (0x000001700701a4)
  2 0x0000017002d6c4 process_breakpoint+0x84() [Z:\home\eric\work\wine\dlls\ntdll\loader.c:3912] in ntdll (0x000001700701a4)
  3 0x000001700354c9 LdrInitializeThunk+0x509(context=<register R13 not accessible in this frame>, unknown2=<internal error>, unknown3=<internal error>, unknown4=<internal error>) [Z:\home\eric\work\wine\dlls\ntdll\loader.c:4200] in ntdll (0x000001700701a4)

where RtlDefaultNpAcl() has nothing to do here (it's the symbol below RIP
and we don't have a symbol with debug information for that address).

Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
---
 dlls/dbghelp/dbghelp.c         |  2 +-
 dlls/dbghelp/dbghelp_private.h |  2 ++
 dlls/dbghelp/dwarf.c           |  2 +-
 dlls/dbghelp/msc.c             |  8 ++++----
 dlls/dbghelp/symbol.c          | 24 +++++++++++++++++++-----
 5 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/dlls/dbghelp/dbghelp.c b/dlls/dbghelp/dbghelp.c
index 6d775b633f8..c154d8d9713 100644
--- a/dlls/dbghelp/dbghelp.c
+++ b/dlls/dbghelp/dbghelp.c
@@ -672,7 +672,7 @@ BOOL WINAPI SymSetScopeFromAddr(HANDLE hProcess, ULONG64 addr)
 
     if (!module_init_pair(&pair, hProcess, addr)) return FALSE;
     pair.pcs->localscope_pc = addr;
-    if ((sym = symt_find_nearest(pair.effective, addr)) != NULL && sym->symt.tag == SymTagFunction)
+    if ((sym = symt_find_symbol_at(pair.effective, addr)) != NULL && sym->symt.tag == SymTagFunction)
         pair.pcs->localscope_symt = &sym->symt;
     else
         pair.pcs->localscope_symt = NULL;
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index c9de237c4b9..507724414a5 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -811,6 +811,8 @@ extern void         copy_symbolW(SYMBOL_INFOW* siw, const SYMBOL_INFO* si) DECLS
 extern void         symbol_setname(SYMBOL_INFO* si, const char* name) DECLSPEC_HIDDEN;
 extern struct symt_ht*
                     symt_find_nearest(struct module* module, DWORD_PTR addr) DECLSPEC_HIDDEN;
+extern struct symt_ht*
+                    symt_find_symbol_at(struct module* module, DWORD_PTR addr) DECLSPEC_HIDDEN;
 extern struct symt_module*
                     symt_new_module(struct module* module) DECLSPEC_HIDDEN;
 extern struct symt_compiland*
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index 0076b19e5cb..b81f83ac90b 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -2584,7 +2584,7 @@ static void dwarf2_set_line_number(struct module* module, ULONG_PTR address,
 
     TRACE("%s %Ix %s %u\n",
           debugstr_w(module->modulename), address, debugstr_a(source_get(module, *psrc)), line);
-    symt = symt_find_nearest(module, address);
+    symt = symt_find_symbol_at(module, address);
     if (symt_check_tag(&symt->symt, SymTagFunction))
     {
         func = (struct symt_function*)symt;
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index 56c0f8b58e8..997661f2912 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -1461,7 +1461,7 @@ static void codeview_snarf_linetab(const struct msc_debug_info* msc_dbg, const B
                  */
                 if (!func || addr >= func->address + func->size)
                 {
-                    func = (struct symt_function*)symt_find_nearest(msc_dbg->module, addr);
+                    func = (struct symt_function*)symt_find_symbol_at(msc_dbg->module, addr);
                     /* FIXME: at least labels support line numbers */
                     if (!symt_check_tag(&func->symt, SymTagFunction) && !symt_check_tag(&func->symt, SymTagInlineSite))
                     {
@@ -1534,7 +1534,7 @@ static void codeview_snarf_linetab2(const struct msc_debug_info* msc_dbg, const
                 lines = CV_RECORD_AFTER(files_hdr);
                 for (i = 0; i < files_hdr->nLines; i++)
                 {
-                    func = (struct symt_function*)symt_find_nearest(msc_dbg->module, lineblk_base + lines[i].offset);
+                    func = (struct symt_function*)symt_find_symbol_at(msc_dbg->module, lineblk_base + lines[i].offset);
                     /* FIXME: at least labels support line numbers */
                     if (!symt_check_tag(&func->symt, SymTagFunction) && !symt_check_tag(&func->symt, SymTagInlineSite))
                     {
@@ -1619,7 +1619,7 @@ static inline void codeview_add_variable(const struct msc_debug_info* msc_dbg,
         loc.kind = in_tls ? loc_tlsrel : loc_absolute;
         loc.reg = 0;
         loc.offset = in_tls ? offset : codeview_get_address(msc_dbg, segment, offset);
-        if (force || in_tls || !symt_find_nearest(msc_dbg->module, loc.offset))
+        if (force || in_tls || !symt_find_symbol_at(msc_dbg->module, loc.offset))
         {
             symt_new_global_variable(msc_dbg->module, compiland,
                                      name, is_local, loc, 0,
@@ -2501,7 +2501,7 @@ static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg,
             if (!top_func)
             {
                 ULONG_PTR parent_addr = codeview_get_address(msc_dbg, sym->sepcode_v3.sectParent, sym->sepcode_v3.offParent);
-                struct symt_ht* parent = symt_find_nearest(msc_dbg->module, parent_addr);
+                struct symt_ht* parent = symt_find_symbol_at(msc_dbg->module, parent_addr);
                 if (symt_check_tag(&parent->symt, SymTagFunction))
                 {
                     struct symt_function* pfunc = (struct symt_function*)parent;
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c
index 64f376b42f0..a81feb56b8d 100644
--- a/dlls/dbghelp/symbol.c
+++ b/dlls/dbghelp/symbol.c
@@ -1027,7 +1027,7 @@ static void symt_get_length(struct module* module, const struct symt* symt, ULON
 
     if (symt_get_info(module, symt, TI_GET_TYPE, &type_index) &&
         symt_get_info(module, symt_index2ptr(module, type_index), TI_GET_LENGTH, size)) return;
-    *size = 0x1000; /* arbitrary value */
+    *size = 1; /* no size info */
 }
 
 /* needed by symt_find_nearest */
@@ -1104,6 +1104,20 @@ struct symt_ht* symt_find_nearest(struct module* module, DWORD_PTR addr)
     return module->addr_sorttab[low];
 }
 
+struct symt_ht* symt_find_symbol_at(struct module* module, DWORD_PTR addr)
+{
+    struct symt_ht* nearest = symt_find_nearest(module, addr);
+    if (nearest)
+    {
+        ULONG64     symaddr, symsize;
+        symt_get_address(&nearest->symt, &symaddr);
+        symt_get_length(module, &nearest->symt, &symsize);
+        if (addr < symaddr || addr >= symaddr + symsize)
+            nearest = NULL;
+    }
+    return nearest;
+}
+
 static BOOL symt_enum_locals_helper(struct module_pair* pair,
                                     const WCHAR* match, const struct sym_enum* se,
                                     struct symt_function* func, const struct vector* v)
@@ -1262,7 +1276,7 @@ struct symt* symt_get_upper_inlined(struct symt_inlinesite* inlined)
 /* lookup in module for an inline site (from addr and inline_ctx) */
 struct symt_inlinesite* symt_find_inlined_site(struct module* module, DWORD64 addr, DWORD inline_ctx)
 {
-    struct symt_ht* symt = symt_find_nearest(module, addr);
+    struct symt_ht* symt = symt_find_symbol_at(module, addr);
 
     if (symt_check_tag(&symt->symt, SymTagFunction))
     {
@@ -1284,7 +1298,7 @@ DWORD symt_get_inlinesite_depth(HANDLE hProcess, DWORD64 addr)
 
     if (module_init_pair(&pair, hProcess, addr))
     {
-        struct symt_ht* symt = symt_find_nearest(pair.effective, addr);
+        struct symt_ht* symt = symt_find_symbol_at(pair.effective, addr);
         if (symt_check_tag(&symt->symt, SymTagFunction))
         {
             struct symt_inlinesite* inlined = symt_find_lowest_inlined((struct symt_function*)symt, addr);
@@ -1518,7 +1532,7 @@ BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD64 Address,
     struct symt_ht*     sym;
 
     if (!module_init_pair(&pair, hProcess, Address)) return FALSE;
-    if ((sym = symt_find_nearest(pair.effective, Address)) == NULL) return FALSE;
+    if ((sym = symt_find_symbol_at(pair.effective, Address)) == NULL) return FALSE;
 
     symt_fill_sym_info(&pair, NULL, &sym->symt, Symbol);
     if (Displacement)
@@ -1905,7 +1919,7 @@ static BOOL get_line_from_addr(HANDLE hProcess, DWORD64 addr,
     struct symt_ht*             symt;
 
     if (!module_init_pair(&pair, hProcess, addr)) return FALSE;
-    if ((symt = symt_find_nearest(pair.effective, addr)) == NULL) return FALSE;
+    if ((symt = symt_find_symbol_at(pair.effective, addr)) == NULL) return FALSE;
 
     if (symt->symt.tag != SymTagFunction && symt->symt.tag != SymTagInlineSite) return FALSE;
     return get_line_from_function(&pair, (struct symt_function*)symt, addr, pdwDisplacement, intl);
-- 
GitLab

https://gitlab.winehq.org/wine/wine/-/merge_requests/14



More information about the wine-devel mailing list