[PATCH 20/22] [WineDbg]: various information printing issues
Eric Pouech
eric.pouech at wanadoo.fr
Fri Nov 24 15:18:42 CST 2006
- 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 spoil space for padding data)
- added support for new wine's dbghelp extension for
local/parameter variables being out of scope
A+
---
programs/winedbg/debugger.h | 1
programs/winedbg/memory.c | 24 ++++++++++--
programs/winedbg/stack.c | 32 +++------------
programs/winedbg/symbol.c | 89 ++++++++++++++++++++++++++++++-------------
4 files changed, 90 insertions(+), 56 deletions(-)
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index fad77f3..e436956 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -370,6 +370,7 @@ extern void symbol_read_symt
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 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);
diff --git a/programs/winedbg/memory.c b/programs/winedbg/memory.c
index cea30e9..e3f11c4 100644
--- a/programs/winedbg/memory.c
+++ b/programs/winedbg/memory.c
@@ -221,7 +221,7 @@ #define DO_DUMP2(_t,_l,_f,_vv) {
#define DO_DUMP(_t,_l,_f) DO_DUMP2(_t,_l,_f,_v)
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 'c': DO_DUMP2(char, 32, " %c", (_v < 0x20) ? ' ' : _v);
case 'b': DO_DUMP2(char, 16, " %02x", (_v) & 0xff);
@@ -484,9 +484,9 @@ void print_basic(const struct dbg_lvalue
case 'x':
if (lvalue->addr.Mode == AddrMode1616 ||
lvalue->addr.Mode == AddrModeReal)
- dbg_printf("0x%04lx", res);
+ dbg_printf("0x%lx", res);
else
- dbg_printf("0x%08lx", res);
+ dbg_printf("0x%lx", res);
break;
case 'd':
@@ -620,6 +620,24 @@ BOOL memory_get_register(DWORD regno, DW
{
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 (buffer) snprintf(buffer, len, "<register not in topmost frame>");
diff --git a/programs/winedbg/stack.c b/programs/winedbg/stack.c
index 1a28dbc..527ed03 100644
--- a/programs/winedbg/stack.c
+++ b/programs/winedbg/stack.c
@@ -184,37 +184,18 @@ unsigned stack_fetch_frames(void)
struct sym_enum
{
- char* tmp;
DWORD frame;
+ BOOL first;
};
static BOOL WINAPI sym_enum_cb(SYMBOL_INFO* sym_info, ULONG size, void* user)
{
struct sym_enum* se = (struct sym_enum*)user;
- char tmp[32];
if (sym_info->Flags & SYMFLAG_PARAMETER)
{
- if (se->tmp[0]) strcat(se->tmp, ", ");
-
- 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);
+ if (!se->first) dbg_printf(", "); else se->first = FALSE;
+ symbol_print_local(sym_info, se->frame, FALSE);
}
return TRUE;
}
@@ -242,18 +223,17 @@ static void stack_print_addr_and_args(in
if (SymFromAddr(dbg_curr_process->handle, ihsf.InstructionOffset, &disp64, si))
{
struct sym_enum se;
- char tmp[1024];
DWORD disp;
dbg_printf(" %s", si->Name);
if (disp64) dbg_printf("+0x%lx", (DWORD_PTR)disp64);
SymSetContext(dbg_curr_process->handle, &ihsf, NULL);
- se.tmp = tmp;
+ se.first = TRUE;
se.frame = ihsf.FrameOffset;
- tmp[0] = '\0';
+ dbg_printf("(");
SymEnumSymbols(dbg_curr_process->handle, 0, NULL, sym_enum_cb, &se);
- if (tmp[0]) dbg_printf("(%s)", tmp);
+ dbg_printf(")");
il.SizeOfStruct = sizeof(il);
if (SymGetLineFromAddr(dbg_curr_process->handle, ihsf.InstructionOffset,
diff --git a/programs/winedbg/symbol.c b/programs/winedbg/symbol.c
index 23f59a6..1b447f5 100644
--- a/programs/winedbg/symbol.c
+++ b/programs/winedbg/symbol.c
@@ -518,46 +518,81 @@ BOOL symbol_get_line(const char* filenam
return TRUE;
}
-static BOOL CALLBACK info_locals_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
+/******************************************************************
+ * 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)
{
- ULONG v, val;
- char buf[128];
- struct dbg_type type;
-
- dbg_printf("\t");
- type.module = sym->ModBase;
- type.id = sym->TypeIndex;
- types_print_type(&type, FALSE);
+ struct dbg_lvalue lvalue;
+ BOOL valtodo = FALSE;
+ char buffer[64];
- buf[0] = '\0';
+ dbg_printf("%s=", sym->Name);
if (sym->Flags & SYMFLAG_REGISTER)
{
- char tmp[32];
DWORD* pval;
- if (!memory_get_register(sym->Register, &pval, tmp, sizeof(tmp)))
+
+ if (memory_get_register(sym->Register, &pval, buffer + 13, sizeof(buffer) - 13))
{
- dbg_printf(" %s (register): %s\n", sym->Name, tmp);
- return TRUE;
+ 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';
}
- sprintf(buf, " in register %s", tmp);
- val = *pval;
}
else if (sym->Flags & SYMFLAG_LOCAL)
{
- type.id = sym->TypeIndex;
- v = (ULONG)ctx + sym->Address;
+ 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';
+ }
+ //dbg_printf("0x%lx", val);
+ if (valtodo)
+ {
+ lvalue.type.module = sym->ModBase;
+ lvalue.type.id = sym->TypeIndex;
+ print_value(&lvalue, 'x', 1);
+ }
- 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;
- }
+ if (detailed)
+ {
+ dbg_printf(" (%s%s)",
+ (sym->Flags & SYMFLAG_PARAMETER) ? "parameter" : "local", buffer);
}
- dbg_printf(" %s = 0x%8.8lx (%s%s)\n", sym->Name, val,
- (sym->Flags & SYMFLAG_PARAMETER) ? "parameter" : "local", buf);
+}
+
+static BOOL CALLBACK info_locals_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
+{
+ struct dbg_type type;
+
+ dbg_printf("\t");
+ type.module = sym->ModBase;
+ type.id = sym->TypeIndex;
+ types_print_type(&type, FALSE);
+
+ dbg_printf(" ");
+ symbol_print_local(sym, (ULONG)ctx, TRUE);
+ dbg_printf("\n");
return TRUE;
}
More information about the wine-patches
mailing list