[PATCH 1/3] [WineDbg]: rewrote the symbol picking mechanism so that it can handle several algorithms
Eric Pouech
eric.pouech at orange.fr
Mon Nov 10 08:02:49 CST 2008
A+
---
programs/winedbg/debugger.h | 6 ++
programs/winedbg/symbol.c | 127 ++++++++++++++++++++++++-------------------
2 files changed, 76 insertions(+), 57 deletions(-)
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index d7ea3c9..6c7cde3 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -395,6 +395,12 @@ extern void symbol_info(const char* str);
extern void symbol_print_local(const SYMBOL_INFO* sym, ULONG base, BOOL detailed);
extern int symbol_info_locals(void);
extern BOOL symbol_is_local(const char* name);
+struct sgv_data;
+typedef enum sym_get_lval (*symbol_picker_t)(const char* name, const struct sgv_data* sgv,
+ struct dbg_lvalue* rtn);
+extern symbol_picker_t symbol_current_picker;
+extern enum sym_get_lval symbol_picker_interactive(const char* name, const struct sgv_data* sgv,
+ struct dbg_lvalue* rtn);
/* tgt_active.c */
extern void dbg_run_debuggee(const char* args);
diff --git a/programs/winedbg/symbol.c b/programs/winedbg/symbol.c
index b4b04e6..56f814b 100644
--- a/programs/winedbg/symbol.c
+++ b/programs/winedbg/symbol.c
@@ -192,6 +192,67 @@ static BOOL CALLBACK sgv_cb(PSYMBOL_INFO sym, ULONG size, PVOID ctx)
return TRUE;
}
+enum sym_get_lval symbol_picker_interactive(const char* name, const struct sgv_data* sgv,
+ struct dbg_lvalue* rtn)
+{
+ char buffer[512];
+ unsigned i;
+
+ if (!dbg_interactiveP)
+ {
+ dbg_printf("More than one symbol named %s, picking the first one\n", name);
+ *rtn = sgv->syms[0].lvalue;
+ return sglv_found;
+ }
+
+ dbg_printf("Many symbols with name '%s', "
+ "choose the one you want (<cr> to abort):\n", name);
+ for (i = 0; i < sgv->num; i++)
+ {
+ if (sgv->num - sgv->num_thunks > 1 && (sgv->syms[i].flags & SYMFLAG_THUNK) && !DBG_IVAR(AlwaysShowThunks))
+ continue;
+ dbg_printf("[%d]: ", i + 1);
+ if (sgv->syms[i].flags & SYMFLAG_LOCAL)
+ {
+ dbg_printf("%s %sof %s\n",
+ sgv->syms[i].flags & SYMFLAG_PARAMETER ? "Parameter" : "Local variable",
+ sgv->syms[i].flags & (SYMFLAG_REGISTER|SYMFLAG_REGREL) ? "(in a register) " : "",
+ name);
+ }
+ else if (sgv->syms[i].flags & SYMFLAG_THUNK)
+ {
+ print_address(&sgv->syms[i].lvalue.addr, TRUE);
+ /* FIXME: should display where the thunks points to */
+ dbg_printf(" thunk %s\n", name);
+ }
+ else
+ {
+ print_address(&sgv->syms[i].lvalue.addr, TRUE);
+ dbg_printf("\n");
+ }
+ }
+ do
+ {
+ i = 0;
+ if (input_read_line("=> ", buffer, sizeof(buffer)))
+ {
+ if (buffer[0] == '\0') return sglv_aborted;
+ i = atoi(buffer);
+ if (i < 1 || i > sgv->num)
+ dbg_printf("Invalid choice %d\n", i);
+ }
+ else return sglv_aborted;
+ } while (i < 1 || i > sgv->num);
+
+ /* The array is 0-based, but the choices are 1..n,
+ * so we have to subtract one before returning.
+ */
+ *rtn = sgv->syms[i - 1].lvalue;
+ return sglv_found;
+}
+
+symbol_picker_t symbol_current_picker = symbol_picker_interactive;
+
/***********************************************************************
* symbol_get_lvalue
*
@@ -317,65 +378,17 @@ enum sym_get_lval symbol_get_lvalue(const char* name, const int lineno,
}
}
- i = 0;
- if (dbg_interactiveP)
- {
- if (sgv.num - sgv.num_thunks > 1 || /* many symbols non thunks (and showing only non thunks) */
- (sgv.num > 1 && DBG_IVAR(AlwaysShowThunks)) || /* many symbols (showing symbols & thunks) */
- (sgv.num == sgv.num_thunks && sgv.num_thunks > 1))
- {
- dbg_printf("Many symbols with name '%s', "
- "choose the one you want (<cr> to abort):\n", name);
- for (i = 0; i < sgv.num; i++)
- {
- if (sgv.num - sgv.num_thunks > 1 && (sgv.syms[i].flags & SYMFLAG_THUNK) && !DBG_IVAR(AlwaysShowThunks))
- continue;
- dbg_printf("[%d]: ", i + 1);
- if (sgv.syms[i].flags & SYMFLAG_LOCAL)
- {
- dbg_printf("%s %sof %s\n",
- sgv.syms[i].flags & SYMFLAG_PARAMETER ? "Parameter" : "Local variable",
- sgv.syms[i].flags & (SYMFLAG_REGISTER|SYMFLAG_REGREL) ? "(in a register) " : "",
- name);
- }
- else if (sgv.syms[i].flags & SYMFLAG_THUNK)
- {
- print_address(&sgv.syms[i].lvalue.addr, TRUE);
- /* FIXME: should display where the thunks points to */
- dbg_printf(" thunk %s\n", name);
- }
- else
- {
- print_address(&sgv.syms[i].lvalue.addr, TRUE);
- dbg_printf("\n");
- }
- }
- do
- {
- i = 0;
- if (input_read_line("=> ", buffer, sizeof(buffer)))
- {
- if (buffer[0] == '\0') return sglv_aborted;
- i = atoi(buffer);
- if (i < 1 || i > sgv.num)
- dbg_printf("Invalid choice %d\n", i);
- }
- else return sglv_aborted;
- } while (i < 1 || i > sgv.num);
-
- /* The array is 0-based, but the choices are 1..n,
- * so we have to subtract one before returning.
- */
- i--;
- }
- }
- else
+ if (sgv.num - sgv.num_thunks > 1 || /* many symbols non thunks (and showing only non thunks) */
+ (sgv.num > 1 && DBG_IVAR(AlwaysShowThunks)) || /* many symbols (showing symbols & thunks) */
+ (sgv.num == sgv.num_thunks && sgv.num_thunks > 1))
{
- /* FIXME: could display the list of non-picked up symbols */
- if (sgv.num > 1)
- dbg_printf("More than one symbol named %s, picking the first one\n", name);
+ return symbol_current_picker(name, &sgv, rtn);
}
- *rtn = sgv.syms[i].lvalue;
+ /* first symbol is the one we want:
+ * - only one symbol found,
+ * - or many symbols but only one non thunk when AlwaysShowThunks is FALSE
+ */
+ *rtn = sgv.syms[0].lvalue;
return sglv_found;
}
More information about the wine-patches
mailing list