winedbg: Various information printing issues.
- in backtraces, (void) functions should be listed with '()' as arguments instead of '' - factorized code for diplaying information about a local/parameter - fixed a couple of bugs here - rewrote format specifiers for print commands (do no waste space for padding data) - added support for new wine's dbghelp extension for local/parameter variables being out of scope
This commit is contained in:
parent
0dd7c44669
commit
62f16d3cd4
|
@ -370,6 +370,7 @@ extern void symbol_read_symtable(const char* filename, unsigned long
|
||||||
extern enum dbg_line_status symbol_get_function_line_status(const ADDRESS64* addr);
|
extern enum dbg_line_status symbol_get_function_line_status(const ADDRESS64* addr);
|
||||||
extern BOOL symbol_get_line(const char* filename, const char* func, IMAGEHLP_LINE* ret);
|
extern BOOL symbol_get_line(const char* filename, const char* func, IMAGEHLP_LINE* ret);
|
||||||
extern void symbol_info(const char* str);
|
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 int symbol_info_locals(void);
|
||||||
extern BOOL symbol_is_local(const char* name);
|
extern BOOL symbol_is_local(const char* name);
|
||||||
|
|
||||||
|
|
|
@ -221,7 +221,7 @@ void memory_examine(const struct dbg_lvalue *lvalue, int count, char format)
|
||||||
#define DO_DUMP(_t,_l,_f) DO_DUMP2(_t,_l,_f,_v)
|
#define DO_DUMP(_t,_l,_f) DO_DUMP2(_t,_l,_f,_v)
|
||||||
|
|
||||||
case 'x': DO_DUMP(int, 4, " %8.8x");
|
case 'x': DO_DUMP(int, 4, " %8.8x");
|
||||||
case 'd': DO_DUMP(unsigned int, 4, " %10d");
|
case 'd': DO_DUMP(unsigned int, 4, " %4.4d");
|
||||||
case 'w': DO_DUMP(unsigned short, 8, " %04x");
|
case 'w': DO_DUMP(unsigned short, 8, " %04x");
|
||||||
case 'c': DO_DUMP2(char, 32, " %c", (_v < 0x20) ? ' ' : _v);
|
case 'c': DO_DUMP2(char, 32, " %c", (_v < 0x20) ? ' ' : _v);
|
||||||
case 'b': DO_DUMP2(char, 16, " %02x", (_v) & 0xff);
|
case 'b': DO_DUMP2(char, 16, " %02x", (_v) & 0xff);
|
||||||
|
@ -482,11 +482,7 @@ void print_basic(const struct dbg_lvalue* lvalue, int count, char format)
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case 'x':
|
case 'x':
|
||||||
if (lvalue->addr.Mode == AddrMode1616 ||
|
dbg_printf("0x%lx", res);
|
||||||
lvalue->addr.Mode == AddrModeReal)
|
|
||||||
dbg_printf("0x%04lx", res);
|
|
||||||
else
|
|
||||||
dbg_printf("0x%08lx", res);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
|
@ -620,6 +616,24 @@ BOOL memory_get_register(DWORD regno, DWORD** value, char* buffer, int len)
|
||||||
{
|
{
|
||||||
const struct dbg_internal_var* div;
|
const struct dbg_internal_var* div;
|
||||||
|
|
||||||
|
/* negative register values are wine's dbghelp hacks
|
||||||
|
* see dlls/dbghelp/dbghelp_internal.h for the details
|
||||||
|
*/
|
||||||
|
switch (regno)
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
if (buffer) snprintf(buffer, len, "<internal error>");
|
||||||
|
return FALSE;
|
||||||
|
case -2:
|
||||||
|
if (buffer) snprintf(buffer, len, "<couldn't compute location>");
|
||||||
|
return FALSE;
|
||||||
|
case -3:
|
||||||
|
if (buffer) snprintf(buffer, len, "<is not available>");
|
||||||
|
return FALSE;
|
||||||
|
case -4:
|
||||||
|
if (buffer) snprintf(buffer, len, "<couldn't read memory>");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
if (dbg_curr_thread->curr_frame != 0)
|
if (dbg_curr_thread->curr_frame != 0)
|
||||||
{
|
{
|
||||||
if (buffer) snprintf(buffer, len, "<register not in topmost frame>");
|
if (buffer) snprintf(buffer, len, "<register not in topmost frame>");
|
||||||
|
|
|
@ -184,37 +184,18 @@ unsigned stack_fetch_frames(void)
|
||||||
|
|
||||||
struct sym_enum
|
struct sym_enum
|
||||||
{
|
{
|
||||||
char* tmp;
|
|
||||||
DWORD frame;
|
DWORD frame;
|
||||||
|
BOOL first;
|
||||||
};
|
};
|
||||||
|
|
||||||
static BOOL WINAPI sym_enum_cb(SYMBOL_INFO* sym_info, ULONG size, void* user)
|
static BOOL WINAPI sym_enum_cb(SYMBOL_INFO* sym_info, ULONG size, void* user)
|
||||||
{
|
{
|
||||||
struct sym_enum* se = (struct sym_enum*)user;
|
struct sym_enum* se = (struct sym_enum*)user;
|
||||||
char tmp[32];
|
|
||||||
|
|
||||||
if (sym_info->Flags & SYMFLAG_PARAMETER)
|
if (sym_info->Flags & SYMFLAG_PARAMETER)
|
||||||
{
|
{
|
||||||
if (se->tmp[0]) strcat(se->tmp, ", ");
|
if (!se->first) dbg_printf(", "); else se->first = FALSE;
|
||||||
|
symbol_print_local(sym_info, se->frame, FALSE);
|
||||||
if (sym_info->Flags & SYMFLAG_REGREL)
|
|
||||||
{
|
|
||||||
unsigned val;
|
|
||||||
DWORD addr = se->frame + sym_info->Address;
|
|
||||||
|
|
||||||
if (!dbg_read_memory((char*)addr, &val, sizeof(val)))
|
|
||||||
snprintf(tmp, sizeof(tmp), "<*** cannot read at 0x%lx ***>", addr);
|
|
||||||
else
|
|
||||||
snprintf(tmp, sizeof(tmp), "0x%x", val);
|
|
||||||
}
|
|
||||||
else if (sym_info->Flags & SYMFLAG_REGISTER)
|
|
||||||
{
|
|
||||||
DWORD* pval;
|
|
||||||
|
|
||||||
if (memory_get_register(sym_info->Register, &pval, tmp, sizeof(tmp)))
|
|
||||||
snprintf(tmp, sizeof(tmp), "0x%lx", *pval);
|
|
||||||
}
|
|
||||||
sprintf(se->tmp + strlen(se->tmp), "%s=%s", sym_info->Name, tmp);
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -242,18 +223,17 @@ static void stack_print_addr_and_args(int nf)
|
||||||
if (SymFromAddr(dbg_curr_process->handle, ihsf.InstructionOffset, &disp64, si))
|
if (SymFromAddr(dbg_curr_process->handle, ihsf.InstructionOffset, &disp64, si))
|
||||||
{
|
{
|
||||||
struct sym_enum se;
|
struct sym_enum se;
|
||||||
char tmp[1024];
|
|
||||||
DWORD disp;
|
DWORD disp;
|
||||||
|
|
||||||
dbg_printf(" %s", si->Name);
|
dbg_printf(" %s", si->Name);
|
||||||
if (disp64) dbg_printf("+0x%lx", (DWORD_PTR)disp64);
|
if (disp64) dbg_printf("+0x%lx", (DWORD_PTR)disp64);
|
||||||
|
|
||||||
SymSetContext(dbg_curr_process->handle, &ihsf, NULL);
|
SymSetContext(dbg_curr_process->handle, &ihsf, NULL);
|
||||||
se.tmp = tmp;
|
se.first = TRUE;
|
||||||
se.frame = ihsf.FrameOffset;
|
se.frame = ihsf.FrameOffset;
|
||||||
tmp[0] = '\0';
|
dbg_printf("(");
|
||||||
SymEnumSymbols(dbg_curr_process->handle, 0, NULL, sym_enum_cb, &se);
|
SymEnumSymbols(dbg_curr_process->handle, 0, NULL, sym_enum_cb, &se);
|
||||||
if (tmp[0]) dbg_printf("(%s)", tmp);
|
dbg_printf(")");
|
||||||
|
|
||||||
il.SizeOfStruct = sizeof(il);
|
il.SizeOfStruct = sizeof(il);
|
||||||
if (SymGetLineFromAddr(dbg_curr_process->handle, ihsf.InstructionOffset,
|
if (SymGetLineFromAddr(dbg_curr_process->handle, ihsf.InstructionOffset,
|
||||||
|
|
|
@ -518,10 +518,71 @@ BOOL symbol_get_line(const char* filename, const char* name, IMAGEHLP_LINE* line
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* symbol_print_local
|
||||||
|
*
|
||||||
|
* Overall format is:
|
||||||
|
* <name>=<value> in non detailed form
|
||||||
|
* <name>=<value> (local|pmt <where>) in detailed form
|
||||||
|
* Note <value> can be an error message in case of error
|
||||||
|
*/
|
||||||
|
void symbol_print_local(const SYMBOL_INFO* sym, ULONG base,
|
||||||
|
BOOL detailed)
|
||||||
|
{
|
||||||
|
struct dbg_lvalue lvalue;
|
||||||
|
BOOL valtodo = FALSE;
|
||||||
|
char buffer[64];
|
||||||
|
|
||||||
|
dbg_printf("%s=", sym->Name);
|
||||||
|
|
||||||
|
if (sym->Flags & SYMFLAG_REGISTER)
|
||||||
|
{
|
||||||
|
DWORD* pval;
|
||||||
|
|
||||||
|
if (memory_get_register(sym->Register, &pval, buffer + 13, sizeof(buffer) - 13))
|
||||||
|
{
|
||||||
|
lvalue.cookie = DLV_HOST;
|
||||||
|
lvalue.addr.Mode = AddrModeFlat;
|
||||||
|
lvalue.addr.Offset = (DWORD_PTR)pval;
|
||||||
|
valtodo = TRUE;
|
||||||
|
memcpy(buffer, " in register ", 13);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dbg_printf(buffer + 13);
|
||||||
|
buffer[0] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (sym->Flags & SYMFLAG_LOCAL)
|
||||||
|
{
|
||||||
|
lvalue.cookie = DLV_TARGET;
|
||||||
|
lvalue.addr.Mode = AddrModeFlat;
|
||||||
|
lvalue.addr.Offset = base + sym->Address;
|
||||||
|
valtodo = TRUE;
|
||||||
|
buffer[0] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dbg_printf("<unexpected symbol flags %lx>\n", sym->Flags);
|
||||||
|
buffer[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valtodo)
|
||||||
|
{
|
||||||
|
lvalue.type.module = sym->ModBase;
|
||||||
|
lvalue.type.id = sym->TypeIndex;
|
||||||
|
print_value(&lvalue, 'x', 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (detailed)
|
||||||
|
{
|
||||||
|
dbg_printf(" (%s%s)",
|
||||||
|
(sym->Flags & SYMFLAG_PARAMETER) ? "parameter" : "local", buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL CALLBACK info_locals_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
|
static BOOL CALLBACK info_locals_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
|
||||||
{
|
{
|
||||||
ULONG v, val;
|
|
||||||
char buf[128];
|
|
||||||
struct dbg_type type;
|
struct dbg_type type;
|
||||||
|
|
||||||
dbg_printf("\t");
|
dbg_printf("\t");
|
||||||
|
@ -529,35 +590,9 @@ static BOOL CALLBACK info_locals_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
|
||||||
type.id = sym->TypeIndex;
|
type.id = sym->TypeIndex;
|
||||||
types_print_type(&type, FALSE);
|
types_print_type(&type, FALSE);
|
||||||
|
|
||||||
buf[0] = '\0';
|
dbg_printf(" ");
|
||||||
|
symbol_print_local(sym, (ULONG)ctx, TRUE);
|
||||||
if (sym->Flags & SYMFLAG_REGISTER)
|
dbg_printf("\n");
|
||||||
{
|
|
||||||
char tmp[32];
|
|
||||||
DWORD* pval;
|
|
||||||
if (!memory_get_register(sym->Register, &pval, tmp, sizeof(tmp)))
|
|
||||||
{
|
|
||||||
dbg_printf(" %s (register): %s\n", sym->Name, tmp);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
sprintf(buf, " in register %s", tmp);
|
|
||||||
val = *pval;
|
|
||||||
}
|
|
||||||
else if (sym->Flags & SYMFLAG_LOCAL)
|
|
||||||
{
|
|
||||||
type.id = sym->TypeIndex;
|
|
||||||
v = (ULONG)ctx + sym->Address;
|
|
||||||
|
|
||||||
if (!dbg_read_memory((void*)v, &val, sizeof(val)))
|
|
||||||
{
|
|
||||||
dbg_printf(" %s (%s) *** cannot read at 0x%08lx\n",
|
|
||||||
sym->Name, (sym->Flags & SYMFLAG_PARAMETER) ? "parameter" : "local",
|
|
||||||
v);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dbg_printf(" %s = 0x%8.8lx (%s%s)\n", sym->Name, val,
|
|
||||||
(sym->Flags & SYMFLAG_PARAMETER) ? "parameter" : "local", buf);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue