winedbg: Rewrote the symbol picking mechanism so that it can handle several algorithms.

This commit is contained in:
Eric Pouech 2008-11-10 15:02:49 +01:00 committed by Alexandre Julliard
parent f96670cb5f
commit 4c00325c3b
2 changed files with 76 additions and 57 deletions

View file

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

View file

@ -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))
{
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--;
}
return symbol_current_picker(name, &sgv, rtn);
}
else
{
/* 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);
}
*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;
}