dbghelp: Introduce symt_find_symbol_at().

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>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Eric Pouech 2022-04-29 11:08:31 +02:00 committed by Alexandre Julliard
parent d106b3c450
commit 99c7818097
5 changed files with 27 additions and 11 deletions

View File

@ -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;

View File

@ -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*

View File

@ -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;

View File

@ -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;

View File

@ -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);