Eric Pouech : winedbg: Extend 'print' command to work with types.
Alexandre Julliard
julliard at winehq.org
Tue May 24 15:55:02 CDT 2022
Module: wine
Branch: master
Commit: 5020371eabba71346b998eddd9c85dcb6b75ed9b
URL: https://source.winehq.org/git/wine.git/?a=commit;h=5020371eabba71346b998eddd9c85dcb6b75ed9b
Author: Eric Pouech <eric.pouech at gmail.com>
Date: Fri May 20 17:03:27 2022 +0200
winedbg: Extend 'print' command to work with types.
'print struct foo' will show all fields of structure
'print enum bar' will show all definitions inside of enum (and their value)
'print /d <type>' will show the type size (in bytes)
Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
---
programs/winedbg/dbg.y | 1 +
programs/winedbg/types.c | 83 ++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 75 insertions(+), 9 deletions(-)
diff --git a/programs/winedbg/dbg.y b/programs/winedbg/dbg.y
index 6faa196e052..235c0928f76 100644
--- a/programs/winedbg/dbg.y
+++ b/programs/winedbg/dbg.y
@@ -225,6 +225,7 @@ x_command:
print_command:
tPRINT expr_lvalue { print_value(&$2, 0, 0); }
| tPRINT tFORMAT expr_lvalue { if (($2 >> 8) == 1) print_value(&$3, $2 & 0xff, 0); else dbg_printf("Count is meaningless in print command\n"); }
+ | tPRINT type_expr { types_print_type(&$2, TRUE); dbg_printf("\n"); }
;
break_command:
diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c
index b8f29058162..bf1276c6adb 100644
--- a/programs/winedbg/types.c
+++ b/programs/winedbg/types.c
@@ -591,7 +591,8 @@ BOOL types_print_type(const struct dbg_type* type, BOOL details)
{
WCHAR* ptr;
const WCHAR* name;
- DWORD tag, udt, count;
+ DWORD tag, udt, count, bitoffset, bt;
+ DWORD64 bitlen;
struct dbg_type subtype;
if (type->id == dbg_itype_none || !types_get_info(type, TI_GET_SYMTAG, &tag))
@@ -605,7 +606,13 @@ BOOL types_print_type(const struct dbg_type* type, BOOL details)
switch (tag)
{
case SymTagBaseType:
- if (details) dbg_printf("Basic<%ls>", name); else dbg_printf("%ls", name);
+ dbg_printf("%ls", name);
+ if (details && types_get_info(type, TI_GET_LENGTH, &bitlen) && types_get_info(type, TI_GET_BASETYPE, &bt))
+ {
+ const char* longness = "";
+ if (bt == btLong || bt == btULong) longness = " long";
+ dbg_printf(": size=%I64d%s", bitlen, longness);
+ }
break;
case SymTagPointerType:
types_get_info(type, TI_GET_TYPE, &subtype.id);
@@ -643,14 +650,21 @@ BOOL types_print_type(const struct dbg_type* type, BOOL details)
type_elt.module = type->module;
type_elt.id = fcp->ChildId[i];
if (!types_get_info(&type_elt, TI_GET_SYMNAME, &ptr) || !ptr) continue;
- dbg_printf("%ls", ptr);
- HeapFree(GetProcessHeap(), 0, ptr);
+ if (!types_get_info(&type_elt, TI_GET_BITPOSITION, &bitoffset) ||
+ !types_get_info(&type_elt, TI_GET_LENGTH, &bitlen))
+ bitlen = ~(DWORD64)0;
if (types_get_info(&type_elt, TI_GET_TYPE, &type_elt.id))
{
- dbg_printf(":");
- types_print_type(&type_elt, details);
+ /* print details of embedded UDT:s */
+ types_print_type(&type_elt, types_get_info(&type_elt, TI_GET_UDTKIND, &udt));
}
- if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
+ else dbg_printf("<unknown>");
+ dbg_printf(" %ls", ptr);
+ HeapFree(GetProcessHeap(), 0, ptr);
+ if (bitlen != ~(DWORD64)0)
+ dbg_printf(" : %I64u", bitlen);
+ dbg_printf(";");
+ if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(" ");
}
}
count -= min(count, 256);
@@ -662,7 +676,7 @@ BOOL types_print_type(const struct dbg_type* type, BOOL details)
case SymTagArrayType:
types_get_info(type, TI_GET_TYPE, &subtype.id);
subtype.module = type->module;
- types_print_type(&subtype, details);
+ types_print_type(&subtype, FALSE);
if (types_get_info(type, TI_GET_COUNT, &count))
dbg_printf(" %ls[%ld]", name, count);
else
@@ -670,6 +684,51 @@ BOOL types_print_type(const struct dbg_type* type, BOOL details)
break;
case SymTagEnum:
dbg_printf("enum %ls", name);
+ if (details &&
+ types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
+ {
+ char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
+ TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
+ WCHAR* ptr;
+ int i;
+ struct dbg_type type_elt;
+ VARIANT variant;
+
+ dbg_printf(" {");
+
+ fcp->Start = 0;
+ while (count)
+ {
+ fcp->Count = min(count, 256);
+ if (types_get_info(type, TI_FINDCHILDREN, fcp))
+ {
+ for (i = 0; i < min(fcp->Count, count); i++)
+ {
+ type_elt.module = type->module;
+ type_elt.id = fcp->ChildId[i];
+ if (!types_get_info(&type_elt, TI_GET_SYMNAME, &ptr) || !ptr) continue;
+ if (!types_get_info(&type_elt, TI_GET_VALUE, &variant) || !ptr) continue;
+ dbg_printf("%ls = ", ptr);
+ switch (V_VT(&variant))
+ {
+ case VT_I1: dbg_printf("%d", V_I1(&variant)); break;
+ case VT_I2: dbg_printf("%d", V_I2(&variant)); break;
+ case VT_I4: dbg_printf("%ld", V_I4(&variant)); break;
+ case VT_I8: dbg_printf("%I64d", V_I8(&variant)); break;
+ case VT_UI1: dbg_printf("%u", V_UI1(&variant)); break;
+ case VT_UI2: dbg_printf("%u", V_UI2(&variant)); break;
+ case VT_UI4: dbg_printf("%lu", V_UI4(&variant)); break;
+ case VT_UI8: dbg_printf("%I64u", V_UI8(&variant)); break;
+ }
+ HeapFree(GetProcessHeap(), 0, ptr);
+ if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
+ }
+ }
+ count -= min(count, 256);
+ fcp->Start += 256;
+ }
+ dbg_printf("}");
+ }
break;
case SymTagFunctionType:
types_get_info(type, TI_GET_TYPE, &subtype.id);
@@ -713,7 +772,13 @@ BOOL types_print_type(const struct dbg_type* type, BOOL details)
dbg_printf(")");
break;
case SymTagTypedef:
- dbg_printf("%ls", name);
+ if (details && types_get_info(type, TI_GET_TYPE, &subtype.id))
+ {
+ dbg_printf("typedef %ls => ", name);
+ subtype.module = type->module;
+ types_print_type(&subtype, FALSE);
+ }
+ else dbg_printf("%ls", name);
break;
default:
WINE_ERR("Unknown type %lu for %ls\n", tag, name);
More information about the wine-cvs
mailing list