[PATCH 01/31] [WineDbg]: typedef

Eric Pouech eric.pouech at wanadoo.fr
Sun Jun 18 14:30:45 CDT 2006


Please use this patch instead of the previous version (fixes a couple
more issues)
- proper hanlding of typedefs
- added types_get_real_type() to get rid of typedef information, 
  and access the real underlying type

A+
---

 programs/winedbg/debugger.h |    1 
 programs/winedbg/memory.c   |   38 +++++++++---------
 programs/winedbg/types.c    |   90 +++++++++++++++++++++++++++----------------
 3 files changed, 76 insertions(+), 53 deletions(-)

diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index 9fee709..c51ccc6 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -392,6 +392,7 @@ extern BOOL             types_deref(cons
 extern BOOL             types_udt_find_element(struct dbg_lvalue* value, const char* name, long int* tmpbuf);
 extern BOOL             types_array_index(const struct dbg_lvalue* value, int index, struct dbg_lvalue* result);
 extern BOOL             types_get_info(const struct dbg_type*, IMAGEHLP_SYMBOL_TYPE_INFO, void*);
+extern BOOL             types_get_real_type(struct dbg_type* type, DWORD* tag);
 extern struct dbg_type  types_find_pointer(const struct dbg_type* type);
 extern struct dbg_type  types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag);
 
diff --git a/programs/winedbg/memory.c b/programs/winedbg/memory.c
index e7792ba..fca6e3d 100644
--- a/programs/winedbg/memory.c
+++ b/programs/winedbg/memory.c
@@ -280,17 +280,16 @@ static void print_typed_basic(const stru
     long double         val_real;
     DWORD64             size64;
     DWORD               tag, size, count, bt;
-    struct dbg_type     rtype;
+    struct dbg_type     type = lvalue->type;
+    struct dbg_type     sub_type;
 
-    if (lvalue->type.id == dbg_itype_none ||
-        !types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
-        return;
+    if (!types_get_real_type(&type, &tag)) return;
 
     switch (tag)
     {
     case SymTagBaseType:
-        if (!types_get_info(&lvalue->type, TI_GET_LENGTH, &size64) ||
-            !types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt))
+        if (!types_get_info(&type, TI_GET_LENGTH, &size64) ||
+            !types_get_info(&type, TI_GET_BASETYPE, &bt))
         {
             WINE_ERR("Couldn't get information\n");
             RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
@@ -326,16 +325,18 @@ static void print_typed_basic(const stru
     case SymTagPointerType:
         if (!memory_read_value(lvalue, sizeof(void*), &val_ptr)) return;
 
-        if (!types_get_info(&lvalue->type, TI_GET_TYPE, &rtype.id) ||
-            rtype.id == dbg_itype_none)
+        sub_type.module = lvalue->type.module;
+        if (!types_get_info(&type, TI_GET_TYPE, &sub_type.id) ||
+            sub_type.id == dbg_itype_none)
         {
             dbg_printf("Internal symbol error: unable to access memory location %p", val_ptr);
             break;
         }
-        rtype.module = lvalue->type.module;
-        if (types_get_info(&rtype, TI_GET_SYMTAG, &tag) && tag == SymTagBaseType &&
-            types_get_info(&rtype, TI_GET_BASETYPE, &bt) && bt == btChar &&
-            types_get_info(&rtype, TI_GET_LENGTH, &size64))
+        if (!types_get_real_type(&sub_type, &tag)) return;
+
+        if (types_get_info(&sub_type, TI_GET_SYMTAG, &tag) && tag == SymTagBaseType &&
+            types_get_info(&sub_type, TI_GET_BASETYPE, &bt) && bt == btChar &&
+            types_get_info(&sub_type, TI_GET_LENGTH, &size64))
         {
             char    buffer[1024];
 
@@ -366,7 +367,7 @@ static void print_typed_basic(const stru
              */
             if (!be_cpu->fetch_integer(lvalue, 4, TRUE, &val_int)) return;
 
-            if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
+            if (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;
@@ -374,19 +375,18 @@ static void print_typed_basic(const stru
                 char                    tmp[256];
                 VARIANT                 variant;
                 int                     i;
-                struct dbg_type         type;
 
                 fcp->Start = 0;
                 while (count)
                 {
                     fcp->Count = min(count, 256);
-                    if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
+                    if (types_get_info(&type, TI_FINDCHILDREN, fcp))
                     {
-                        type.module = lvalue->type.module;
+                        sub_type.module = type.module;
                         for (i = 0; i < min(fcp->Count, count); i++)
                         {
-                            type.id = fcp->ChildId[i];
-                            if (!types_get_info(&type, TI_GET_VALUE, &variant)) 
+                            sub_type.id = fcp->ChildId[i];
+                            if (!types_get_info(&sub_type, TI_GET_VALUE, &variant)) 
                                 continue;
                             switch (variant.n1.n2.vt)
                             {
@@ -396,7 +396,7 @@ static void print_typed_basic(const stru
                             if (ok)
                             {
                                 ptr = NULL;
-                                types_get_info(&type, TI_GET_SYMNAME, &ptr);
+                                types_get_info(&sub_type, TI_GET_SYMNAME, &ptr);
                                 if (!ptr) continue;
                                 WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
                                 HeapFree(GetProcessHeap(), 0, ptr);
diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c
index 05e1e89..7ea1aa5 100644
--- a/programs/winedbg/types.c
+++ b/programs/winedbg/types.c
@@ -30,6 +30,24 @@ #include "wine/debug.h"
 WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
 
 /******************************************************************
+ *		types_get_real_type
+ *
+ * Get rid of any potential typedef in the lvalue's type to get
+ * to the 'real' type (the one we can work upon).
+ */
+BOOL types_get_real_type(struct dbg_type* type, DWORD* tag)
+{
+    if (type->id == dbg_itype_none) return FALSE;
+    do
+    {
+        if (!types_get_info(type, TI_GET_SYMTAG, tag))
+            return FALSE;
+        if (*tag != SymTagTypedef) return TRUE;
+    } while (types_get_info(type, TI_GET_TYPE, &type->id));
+    return FALSE;
+}
+
+/******************************************************************
  *		types_extract_as_integer
  *
  * Given a lvalue, try to get an integral (or pointer/address) value
@@ -41,12 +59,12 @@ long int types_extract_as_integer(const 
     LONGLONG            val;
     DWORD               tag, bt;
     DWORD64             size;
+    struct dbg_type     type = lvalue->type;
 
-    if (lvalue->type.id == dbg_itype_none ||
-        !types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
+    if (!types_get_real_type(&type, &tag))
         RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
 
-    if (lvalue->type.id == dbg_itype_segptr)
+    if (type.id == dbg_itype_segptr)
     {
         return (long int)memory_to_linear_addr(&lvalue->addr);
     }
@@ -54,8 +72,8 @@ long int types_extract_as_integer(const 
     switch (tag)
     {
     case SymTagBaseType:
-        if (!types_get_info(&lvalue->type, TI_GET_LENGTH, &size) ||
-            !types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt))
+        if (!types_get_info(&type, TI_GET_LENGTH, &size) ||
+            !types_get_info(&type, TI_GET_BASETYPE, &bt))
         {
             WINE_ERR("Couldn't get information\n");
             RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
@@ -133,7 +151,8 @@ void types_extract_as_address(const stru
  */
 BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result)
 {
-    DWORD       tag;
+    struct dbg_type     type = lvalue->type;
+    DWORD               tag;
 
     memset(result, 0, sizeof(*result));
     result->type.id = dbg_itype_none;
@@ -142,12 +161,11 @@ BOOL types_deref(const struct dbg_lvalue
     /*
      * Make sure that this really makes sense.
      */
-    if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag) ||
-        tag != SymTagPointerType ||
+    if (!types_get_real_type(&type, &tag) || tag != SymTagPointerType ||
         !memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset) ||
-        !types_get_info(&lvalue->type, TI_GET_TYPE, &result->type.id))
+        !types_get_info(&type, TI_GET_TYPE, &result->type.id))
         return FALSE;
-    result->type.module = lvalue->type.module;
+    result->type.module = type.module;
     result->cookie = DLV_TARGET;
     /* FIXME: this is currently buggy.
      * there is no way to tell were the deref:ed value is...
@@ -219,7 +237,6 @@ static BOOL types_get_udt_element_lvalue
     else
     {
         if (!memory_read_value(lvalue, sizeof(*tmpbuf), tmpbuf)) return FALSE;
-
     }
     return TRUE;
 }
@@ -279,15 +296,15 @@ BOOL types_udt_find_element(struct dbg_l
 BOOL types_array_index(const struct dbg_lvalue* lvalue, int index, 
                        struct dbg_lvalue* result)
 {
-    DWORD       tag, count;
-    DWORD64     length;
+    struct dbg_type     type = lvalue->type;
+    DWORD               tag, count;
+    DWORD64             length;
 
-    if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
-        return FALSE;
+    if (!types_get_real_type(&type, &tag)) return FALSE;
     switch (tag)
     {
     case SymTagArrayType:
-        types_get_info(&lvalue->type, TI_GET_COUNT, &count);
+        types_get_info(&type, TI_GET_COUNT, &count);
         if (index < 0 || index >= count) return FALSE;
         /* fall through */
     case SymTagPointerType:
@@ -296,7 +313,7 @@ BOOL types_array_index(const struct dbg_
         /*
          * Get the base type, so we know how much to index by.
          */
-        types_get_info(&lvalue->type, TI_GET_TYPE, &result->type.id);
+        types_get_info(&type, TI_GET_TYPE, &result->type.id);
         types_get_info(&result->type, TI_GET_LENGTH, &length);
         memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset);
         result->addr.Offset += index * (DWORD)length;
@@ -399,13 +416,20 @@ struct dbg_type types_find_type(unsigned
  */
 void print_value(const struct dbg_lvalue* lvalue, char format, int level)
 {
+    struct dbg_type     type = lvalue->type;
     struct dbg_lvalue   lvalue_field;
     int		        i;
     DWORD               tag;
     DWORD               count;
     DWORD64             size;
 
-    if (lvalue->type.id == dbg_itype_none)
+    if (!types_get_real_type(&type, &tag))
+    {
+        WINE_FIXME("---error\n");
+        return;
+    }
+
+    if (type.id == dbg_itype_none)
     {
         /* No type, just print the addr value */
         print_bare_address(&lvalue->addr);
@@ -418,47 +442,45 @@ void print_value(const struct dbg_lvalue
         format = '\0';
     }
 
-    if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
-    {
-        WINE_FIXME("---error\n");
-        return;
-    }
     switch (tag)
     {
     case SymTagBaseType:
     case SymTagEnum:
     case SymTagPointerType:
+        /* FIXME: this in not 100% optimal (as we're going through the typedef handling
+         * stuff again
+         */
         print_basic(lvalue, 1, format);
         break;
     case SymTagUDT:
-        if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
+        if (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;
             char                        tmp[256];
             long int                    tmpbuf;
-            struct dbg_type             type;
+            struct dbg_type             sub_type;
 
             dbg_printf("{");
             fcp->Start = 0;
             while (count)
             {
                 fcp->Count = min(count, 256);
-                if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
+                if (types_get_info(&type, TI_FINDCHILDREN, fcp))
                 {
                     for (i = 0; i < min(fcp->Count, count); i++)
                     {
                         ptr = NULL;
-                        type.module = lvalue->type.module;
-                        type.id = fcp->ChildId[i];
-                        types_get_info(&type, TI_GET_SYMNAME, &ptr);
+                        sub_type.module = type.module;
+                        sub_type.id = fcp->ChildId[i];
+                        types_get_info(&sub_type, TI_GET_SYMNAME, &ptr);
                         if (!ptr) continue;
                         WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
                         dbg_printf("%s=", tmp);
                         HeapFree(GetProcessHeap(), 0, ptr);
                         lvalue_field = *lvalue;
-                        if (types_get_udt_element_lvalue(&lvalue_field, &type, &tmpbuf))
+                        if (types_get_udt_element_lvalue(&lvalue_field, &sub_type, &tmpbuf))
                         {
                             print_value(&lvalue_field, format, level + 1);
                         }
@@ -476,8 +498,8 @@ void print_value(const struct dbg_lvalue
          * Loop over all of the entries, printing stuff as we go.
          */
         count = 1; size = 1;
-        types_get_info(&lvalue->type, TI_GET_COUNT, &count);
-        types_get_info(&lvalue->type, TI_GET_LENGTH, &size);
+        types_get_info(&type, TI_GET_COUNT, &count);
+        types_get_info(&type, TI_GET_LENGTH, &size);
 
         if (size == count)
 	{
@@ -495,7 +517,7 @@ void print_value(const struct dbg_lvalue
             break;
         }
         lvalue_field = *lvalue;
-        types_get_info(&lvalue->type, TI_GET_TYPE, &lvalue_field.type.id);
+        types_get_info(&type, TI_GET_TYPE, &lvalue_field.type.id);
         dbg_printf("{");
         for (i = 0; i < count; i++)
 	{
@@ -508,7 +530,7 @@ void print_value(const struct dbg_lvalue
         dbg_printf("Function ");
         print_bare_address(&lvalue->addr);
         dbg_printf(": ");
-        types_print_type(&lvalue->type, FALSE);
+        types_print_type(&type, FALSE);
         break;
     case SymTagTypedef:
         lvalue_field = *lvalue;



More information about the wine-patches mailing list