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@gmail.com
-- v2: dlls/dbghelp: introduce symt_find_symbol_at()
From: Eric Pouech eric.pouech@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@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);