[PATCH 09/10] programs/winedbg: use SymSetScopeFromAddr() instead of SymSetContext()

Eric Pouech eric.pouech at gmail.com
Tue Oct 26 04:46:01 CDT 2021


this allows to simplify a bit the frame internal storage
(no longer using IMAGEHLP_STACK_FRAME structure)

Signed-off-by: Eric Pouech <eric.pouech at gmail.com>

---
 programs/winedbg/debugger.h |    1 
 programs/winedbg/stack.c    |   88 ++++++++++++++++++-------------------------
 programs/winedbg/symbol.c   |   23 ++++++-----
 3 files changed, 48 insertions(+), 64 deletions(-)

diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index 7af9e0d75e4..498a1a0516d 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -386,7 +386,6 @@ extern void             source_free_files(struct dbg_process* p);
 extern void             stack_info(int len);
 extern void             stack_backtrace(DWORD threadID);
 extern BOOL             stack_set_frame(int newframe);
-extern BOOL             stack_get_current_frame(IMAGEHLP_STACK_FRAME* ihsf);
 extern BOOL             stack_get_register_frame(const struct dbg_internal_var* div, DWORD_PTR** pval);
 extern unsigned         stack_fetch_frames(const dbg_ctx_t *ctx);
 extern BOOL             stack_get_current_symbol(SYMBOL_INFO* sym);
diff --git a/programs/winedbg/stack.c b/programs/winedbg/stack.c
index 9c22587a864..317eb5626dd 100644
--- a/programs/winedbg/stack.c
+++ b/programs/winedbg/stack.c
@@ -64,6 +64,26 @@ void stack_info(int len)
     }
 }
 
+static BOOL stack_set_local_scope(void)
+{
+    struct dbg_frame* frm = stack_get_thread_frame(dbg_curr_thread, dbg_curr_thread->curr_frame);
+
+    if (!frm) return FALSE;
+    /* if we're not the first frame, linear_pc is the return address
+     * after the call instruction (at least on most processors I know of).
+     * However, there are cases where this address is outside of the
+     * current function or inline site.
+     * This happens when the called function is marked <NO RETURN>, in which
+     * case the compiler can omit the epilog (gcc 4 does it).
+     * This happens also for inline sites, where the epilog (of the inline
+     * site) isn't present.
+     * Therefore, we decrement linear_pc in order to ensure that
+     * the considered address is really inside the current function or inline site.
+     */
+    return SymSetScopeFromAddr(dbg_curr_process->handle,
+                               (dbg_curr_thread->curr_frame) ? frm->linear_pc - 1 : frm->linear_pc);
+}
+
 static BOOL stack_set_frame_internal(int newframe)
 {
     if (newframe >= dbg_curr_thread->num_frames)
@@ -73,42 +93,12 @@ static BOOL stack_set_frame_internal(int newframe)
 
     if (dbg_curr_thread->curr_frame != newframe)
     {
-        IMAGEHLP_STACK_FRAME    ihsf;
-
         dbg_curr_thread->curr_frame = newframe;
-        stack_get_current_frame(&ihsf);
-        SymSetContext(dbg_curr_process->handle, &ihsf, NULL);
+        stack_set_local_scope();
     }
     return TRUE;
 }
 
-static BOOL stack_get_frame(int nf, IMAGEHLP_STACK_FRAME* ihsf)
-{
-    memset(ihsf, 0, sizeof(*ihsf));
-    ihsf->InstructionOffset = dbg_curr_thread->frames[nf].linear_pc;
-    /* if we're not the first frame, InstructionOffset is the return address
-     * after the call instruction (at least on most processors I know of).
-     * However, there are cases where this address is outside of the current function.
-     * This happens when the called function is marked <NO RETURN>, in which
-     * case the compiler can omit the epilog (gcc 4 does it)
-     * Therefore, we decrement InstructionOffset in order to ensure that
-     * the considered address is really inside the current function.
-     */
-    if (nf) ihsf->InstructionOffset--;
-    ihsf->FrameOffset = dbg_curr_thread->frames[nf].linear_frame;
-    ihsf->StackOffset = dbg_curr_thread->frames[nf].linear_stack;
-    return TRUE;
-}
-
-BOOL stack_get_current_frame(IMAGEHLP_STACK_FRAME* ihsf)
-{
-    /*
-     * If we don't have a valid backtrace, then just return.
-     */
-    if (dbg_curr_thread->frames == NULL) return FALSE;
-    return stack_get_frame(dbg_curr_thread->curr_frame, ihsf);
-}
-
 BOOL stack_get_register_frame(const struct dbg_internal_var* div, DWORD_PTR** pval)
 {
     struct dbg_frame* currfrm = stack_get_curr_frame();
@@ -155,12 +145,11 @@ BOOL stack_set_frame(int newframe)
  */
 BOOL stack_get_current_symbol(SYMBOL_INFO* symbol)
 {
-    IMAGEHLP_STACK_FRAME        ihsf;
     DWORD64                     disp;
+    struct dbg_frame*           frm = stack_get_curr_frame();
 
-    if (!stack_get_current_frame(&ihsf)) return FALSE;
-    return SymFromAddr(dbg_curr_process->handle, ihsf.InstructionOffset,
-                       &disp, symbol);
+    if (frm == NULL) return FALSE;
+    return SymFromAddr(dbg_curr_process->handle, frm->linear_pc, &disp, symbol);
 }
 
 static BOOL CALLBACK stack_read_mem(HANDLE hProc, DWORD64 addr, 
@@ -260,27 +249,26 @@ static BOOL WINAPI sym_enum_cb(PSYMBOL_INFO sym_info, ULONG size, PVOID user)
     return TRUE;
 }
 
-static void stack_print_addr_and_args(int nf)
+static void stack_print_addr_and_args(void)
 {
     char                        buffer[sizeof(SYMBOL_INFO) + 256];
     SYMBOL_INFO*                si = (SYMBOL_INFO*)buffer;
-    IMAGEHLP_STACK_FRAME        ihsf;
     IMAGEHLP_LINE64             il;
     IMAGEHLP_MODULE             im;
     DWORD64                     disp64;
+    struct dbg_frame*           frm = stack_get_curr_frame();
 
-    print_bare_address(&dbg_curr_thread->frames[nf].addr_pc);
-
-    stack_get_frame(nf, &ihsf);
+    if (!frm) return;
+    print_bare_address(&frm->addr_pc);
 
     /* grab module where symbol is. If we don't have a module, we cannot print more */
     im.SizeOfStruct = sizeof(im);
-    if (!SymGetModuleInfo(dbg_curr_process->handle, ihsf.InstructionOffset, &im))
+    if (!SymGetModuleInfo(dbg_curr_process->handle, frm->linear_pc, &im))
         return;
 
     si->SizeOfStruct = sizeof(*si);
     si->MaxNameLen   = 256;
-    if (SymFromAddr(dbg_curr_process->handle, ihsf.InstructionOffset, &disp64, si))
+    if (SymFromAddr(dbg_curr_process->handle, frm->linear_pc, &disp64, si))
     {
         struct sym_enum se;
         DWORD           disp;
@@ -288,21 +276,19 @@ static void stack_print_addr_and_args(int nf)
         dbg_printf(" %s", si->Name);
         if (disp64) dbg_printf("+0x%I64x", disp64);
 
-        SymSetContext(dbg_curr_process->handle, &ihsf, NULL);
+        stack_set_local_scope();
         se.first = TRUE;
-        se.frame = ihsf.FrameOffset;
+        se.frame = frm->linear_frame;
         dbg_printf("(");
         SymEnumSymbols(dbg_curr_process->handle, 0, NULL, sym_enum_cb, &se);
         dbg_printf(")");
 
         il.SizeOfStruct = sizeof(il);
-        if (SymGetLineFromAddr64(dbg_curr_process->handle,
-				 ihsf.InstructionOffset, &disp, &il))
+        if (SymGetLineFromAddr64(dbg_curr_process->handle, frm->linear_pc, &disp, &il))
             dbg_printf(" [%s:%u]", il.FileName, il.LineNumber);
         dbg_printf(" in %s", im.ModuleName);
     }
-    else dbg_printf(" in %s (+0x%I64x)",
-                    im.ModuleName, ihsf.InstructionOffset - im.BaseOfImage);
+    else dbg_printf(" in %s (+0x%Ix)", im.ModuleName, frm->linear_pc - im.BaseOfImage);
 }
 
 /******************************************************************
@@ -313,7 +299,6 @@ static void stack_print_addr_and_args(int nf)
 static void backtrace(void)
 {
     unsigned                    cf = dbg_curr_thread->curr_frame;
-    IMAGEHLP_STACK_FRAME        ihsf;
 
     dbg_printf("Backtrace:\n");
     for (dbg_curr_thread->curr_frame = 0;
@@ -323,7 +308,7 @@ static void backtrace(void)
         dbg_printf("%s%d ", 
                    (cf == dbg_curr_thread->curr_frame ? "=>" : "  "),
                    dbg_curr_thread->curr_frame);
-        stack_print_addr_and_args(dbg_curr_thread->curr_frame);
+        stack_print_addr_and_args();
         dbg_printf(" (");
         print_bare_address(&dbg_curr_thread->frames[dbg_curr_thread->curr_frame].addr_frame);
         dbg_printf(")\n");
@@ -331,8 +316,7 @@ static void backtrace(void)
     /* reset context to current stack frame */
     dbg_curr_thread->curr_frame = cf;
     if (!dbg_curr_thread->frames) return;
-    stack_get_frame(dbg_curr_thread->curr_frame, &ihsf);
-    SymSetContext(dbg_curr_process->handle, &ihsf, NULL);
+    stack_set_local_scope();
 }
 
 /******************************************************************
diff --git a/programs/winedbg/symbol.c b/programs/winedbg/symbol.c
index 7067b886f44..67be370cc5b 100644
--- a/programs/winedbg/symbol.c
+++ b/programs/winedbg/symbol.c
@@ -366,7 +366,7 @@ enum sym_get_lval symbol_get_lvalue(const char* name, const int lineno,
     int		                i;
     char                        buffer[512];
     BOOL                        opt;
-    IMAGEHLP_STACK_FRAME        ihsf;
+    struct dbg_frame*           frm;
 
     if (strlen(name) + 4 > sizeof(buffer))
     {
@@ -421,9 +421,9 @@ enum sym_get_lval symbol_get_lvalue(const char* name, const int lineno,
     SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES, opt);
 
     /* now grab local symbols */
-    if (stack_get_current_frame(&ihsf) && sgv.num < NUMDBGV)
+    if ((frm = stack_get_curr_frame()) && sgv.num < NUMDBGV)
     {
-        sgv.frame_offset = ihsf.FrameOffset;
+        sgv.frame_offset = frm->linear_frame;
         SymEnumSymbols(dbg_curr_process->handle, 0, name, sgv_cb, (void*)&sgv);
     }
 
@@ -491,16 +491,16 @@ enum sym_get_lval symbol_get_lvalue(const char* name, const int lineno,
 BOOL symbol_is_local(const char* name)
 {
     struct sgv_data             sgv;
-    IMAGEHLP_STACK_FRAME        ihsf;
+    struct dbg_frame*           frm;
 
     sgv.num        = 0;
     sgv.num_thunks = 0;
     sgv.name       = name;
     sgv.do_thunks  = FALSE;
 
-    if (stack_get_current_frame(&ihsf))
+    if ((frm = stack_get_curr_frame()))
     {
-        sgv.frame_offset = ihsf.FrameOffset;
+        sgv.frame_offset = frm->linear_frame;
         SymEnumSymbols(dbg_curr_process->handle, 0, name, sgv_cb, (void*)&sgv);
     }
     return sgv.num > 0;
@@ -748,15 +748,16 @@ static BOOL CALLBACK info_locals_cb(PSYMBOL_INFO sym, ULONG size, PVOID ctx)
 
 BOOL symbol_info_locals(void)
 {
-    IMAGEHLP_STACK_FRAME        ihsf;
     ADDRESS64                   addr;
+    struct dbg_frame*           frm;
+
+    if (!(frm = stack_get_curr_frame())) return FALSE;
 
-    stack_get_current_frame(&ihsf);
     addr.Mode = AddrModeFlat;
-    addr.Offset = ihsf.InstructionOffset;
+    addr.Offset = frm->linear_pc;
     print_address(&addr, FALSE);
-    dbg_printf(": (%0*lx)\n", ADDRWIDTH, (DWORD_PTR)ihsf.FrameOffset);
-    SymEnumSymbols(dbg_curr_process->handle, 0, NULL, info_locals_cb, (void*)(DWORD_PTR)ihsf.FrameOffset);
+    dbg_printf(": (%0*lx)\n", ADDRWIDTH, (DWORD_PTR)frm->linear_frame);
+    SymEnumSymbols(dbg_curr_process->handle, 0, NULL, info_locals_cb, (void*)frm->linear_frame);
 
     return TRUE;
 




More information about the wine-devel mailing list