mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-01 09:50:52 +00:00
winedbg: Rewrote the symbol picking mechanism so that it can handle several algorithms.
This commit is contained in:
parent
f96670cb5f
commit
4c00325c3b
2 changed files with 76 additions and 57 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue