WineDbg

Eric Pouech eric.pouech at wanadoo.fr
Sat May 25 13:43:50 CDT 2002


this patch makes the type handling a bit more robust
it also allows to use the /u format modifier to display Unicode strings
I didn't test it with complicated strings (ie, that convert easily to
ANSI strings), but it should work in the wineconsole 
(if you have a proper font selected)

A+
-------------- next part --------------
Name:          wdbg_uni_typ
ChangeLog:     hacked unicode printing feature (x /u)
	made the type casts a bit more robust
License:       X11
GenDate:       2002/05/25 18:38:33 UTC
ModifiedFiles: debugger/dbg.y debugger/expr.c debugger/info.c debugger/memory.c debugger/types.c debugger/winedbg.c debugger/debugger.h
AddedFiles:    
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/debugger/dbg.y,v
retrieving revision 1.54
diff -u -u -r1.54 dbg.y
--- debugger/dbg.y	27 Apr 2002 21:16:28 -0000	1.54
+++ debugger/dbg.y	27 Apr 2002 21:37:05 -0000
@@ -86,7 +86,7 @@
 %nonassoc ':'
 
 %type <expression> expr lval lvalue 
-%type <type> type_cast type_expr
+%type <type> type_expr
 %type <value> expr_addr lval_addr
 %type <integer> expr_value
 %type <string> pathname identifier
@@ -266,11 +266,8 @@
     | tNOPROCESS tSTRING tEOL	{ DEBUG_Printf(DBG_CHN_MESG, "No process loaded, cannot execute '%s'\n", $2); }
     ;
 
-type_cast: '(' type_expr ')'    { $$ = $2; }
-    ;
-
 type_expr:
-      type_expr '*'		{ $$ = DEBUG_FindOrMakePointerType($1); }
+      type_expr '*'		{ $$ = $1 ? DEBUG_FindOrMakePointerType($1) : NULL; }
     | tINT			{ $$ = DEBUG_GetBasicType(DT_BASIC_INT); }
     | tCHAR			{ $$ = DEBUG_GetBasicType(DT_BASIC_CHAR); }
     | tLONG tINT		{ $$ = DEBUG_GetBasicType(DT_BASIC_LONGINT); }
@@ -344,7 +341,7 @@
     | '(' expr ')'               { $$ = $2; }
     | '*' expr %prec OP_DEREF    { $$ = DEBUG_UnopExpr(EXP_OP_DEREF, $2); }
     | '&' expr %prec OP_DEREF    { $$ = DEBUG_UnopExpr(EXP_OP_ADDR, $2); }
-    | type_cast expr %prec OP_DEREF { $$ = DEBUG_TypeCastExpr($1, $2); } 
+    | '(' type_expr ')' expr %prec OP_DEREF { $$ = DEBUG_TypeCastExpr($2, $4); } 
     ;
 
 /*
Index: debugger/expr.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/debugger/expr.c,v
retrieving revision 1.25
diff -u -u -r1.25 expr.c
--- debugger/expr.c	9 Mar 2002 23:50:37 -0000	1.25
+++ debugger/expr.c	21 Apr 2002 13:56:51 -0000
@@ -323,6 +323,11 @@
     case EXPR_TYPE_CAST:
       rtn = DEBUG_EvalExpr(exp->un.cast.expr);
       rtn.type = exp->un.cast.cast;
+      if (!rtn.type)
+      {
+	  DEBUG_Printf(DBG_CHN_MESG, "Can't cast to unknown type\n");
+	  RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
+      }
       if (DEBUG_GetType(rtn.type) == DT_POINTER)
 	 rtn.cookie = DV_TARGET;
       break;
Index: debugger/info.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/debugger/info.c,v
retrieving revision 1.23
diff -u -u -r1.23 info.c
--- debugger/info.c	9 Mar 2002 23:50:37 -0000	1.23
+++ debugger/info.c	11 May 2002 08:43:30 -0000
@@ -36,97 +36,107 @@
  */
 void DEBUG_PrintBasic( const DBG_VALUE* value, int count, char format )
 {
-  char        * default_format;
-  long long int res;
-
-  assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
-  if( value->type == NULL ) 
+    char        * default_format;
+    long long int res;
+    
+    assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
+    if (value->type == NULL) 
     {
-      DEBUG_Printf(DBG_CHN_MESG, "Unable to evaluate expression\n");
-      return;
+        DEBUG_Printf(DBG_CHN_MESG, "Unable to evaluate expression\n");
+        return;
     }
-  
-  default_format = NULL;
-  res = DEBUG_GetExprValue(value, &default_format);
-
-  switch(format)
+    
+    default_format = NULL;
+    res = DEBUG_GetExprValue(value, &default_format);
+    
+    switch (format)
     {
     case 'x':
-      if (value->addr.seg) 
+        if (value->addr.seg) 
 	{
-	  DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "0x%04lx", (long unsigned int) res );
+            DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "0x%04lx", (long unsigned int)res);
 	}
-      else 
+        else 
 	{
-	  DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "0x%08lx", (long unsigned int) res );
+            DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "0x%08lx", (long unsigned int)res);
 	}
-      break;
-      
+        break;
+        
     case 'd':
-      DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "%ld\n", (long int) res );
-      break;
-      
+        DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "%ld\n", (long int)res);
+        break;
+        
     case 'c':
-      DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "%d = '%c'",
-				   (char)(res & 0xff), (char)(res & 0xff) );
-      break;
-      
+        DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "%d = '%c'",
+                                    (char)(res & 0xff), (char)(res & 0xff));
+        break;
+        
+    case 'u':
+    {
+        WCHAR wch = (WCHAR)(res & 0xFFFF);
+        DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "%d = '", (unsigned)(res & 0xffff));
+        DEBUG_OutputW(DBG_CHN_MESG, &wch, 1);
+        DEBUG_Printf(DBG_CHN_MESG, "'");
+    }
+    break;
+    
     case 'i':
     case 's':
     case 'w':
     case 'b':
-      DEBUG_Printf( DBG_CHN_MESG, "Format specifier '%c' is meaningless in 'print' command\n", format );
+        DEBUG_Printf(DBG_CHN_MESG, "Format specifier '%c' is meaningless in 'print' command\n", format);
     case 0:
-      if( default_format != NULL )
+        if (default_format != NULL)
 	{
-	  if (strstr(default_format, "%S") != NULL)
+            if (strstr(default_format, "%S") != NULL)
 	    {
-	       char* 	ptr;
-	       int	state = 0;
-
-	       /* FIXME: simplistic implementation for default_format being
-		* foo%Sbar => will print foo, then string then bar
-		*/
-	       for (ptr = default_format; *ptr; ptr++) 
-	       {
-		  if (*ptr == '%') state++;
-		  else if (state == 1) 
+                char* 	ptr;
+                int	state = 0;
+                
+                /* FIXME: simplistic implementation for default_format being
+                 * foo%Sbar => will print foo, then string then bar
+                 */
+                for (ptr = default_format; *ptr; ptr++) 
+                {
+                    if (*ptr == '%') 
+                    { 
+                        state++;
+                    }       
+                    else if (state == 1) 
 		    {
-		       if (*ptr == 'S') 
-			 {
-			    char 	ch;
-			    char*	str = (char*)(long)res;
-
-			    for (; DEBUG_READ_MEM(str, &ch, 1) && ch; str++) {
-			       DEBUG_Output(DBG_CHN_MESG, &ch, 1);
-			       DEBUG_nchar++;
-			    }
-			 }
-		       else 
-			 {
+                        if (*ptr == 'S') 
+                        {
+                            DBG_ADDR    addr;
+                            
+                            addr.seg = 0;
+                            addr.off = (long)res;
+                            DEBUG_nchar += DEBUG_PrintStringA(DBG_CHN_MESG, &addr, -1);
+                        }
+                        else 
+                        {
 			    /* shouldn't happen */
 			    DEBUG_Printf(DBG_CHN_MESG, "%%%c", *ptr);
 			    DEBUG_nchar += 2;
-			 }
-		       state = 0;
+                        }
+                        state = 0;
 		    }
-		  else
+                    else
 		    {
-		       DEBUG_Output(DBG_CHN_MESG, ptr, 1);
-		       DEBUG_nchar++;
+                        DEBUG_OutputA(DBG_CHN_MESG, ptr, 1);
+                        DEBUG_nchar++;
 		    }
-	       }
+                }
 	    } 
-	  else if (strcmp(default_format, "%B") == 0)
+            else if (strcmp(default_format, "%B") == 0)
             {
-	       DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "%s", res ? "true" : "false");
+                DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "%s", res ? "true" : "false");
             }
-          else
+            else
 	    {
-	       DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, default_format, res );
+                DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, default_format, res);
 	    }
 	}
-      break;
+        break;
     }
 }
 
Index: debugger/memory.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/debugger/memory.c,v
retrieving revision 1.27
diff -u -u -r1.27 memory.c
--- debugger/memory.c	26 Apr 2002 19:05:16 -0000	1.27
+++ debugger/memory.c	27 Apr 2002 21:35:39 -0000
@@ -276,33 +276,15 @@
 
     switch(format)
     {
-	case 'u': {
-		WCHAR wch;
-		if (count == 1) count = 256;
-                while (count--)
-                {
-		    if (!DEBUG_READ_MEM_VERBOSE(pnt, &wch, sizeof(wch)) || !wch)
-		       break;
-                    pnt += sizeof(wch);
-                    DEBUG_Printf(DBG_CHN_MESG, "%c", (char)wch);
-                }
-		DEBUG_Printf(DBG_CHN_MESG,"\n");
+         case 'u':
+                if (count == 1) count = 256;
+                DEBUG_nchar += DEBUG_PrintStringW(DBG_CHN_MESG, &value.addr, count);
+		DEBUG_Printf(DBG_CHN_MESG, "\n");
 		return;
-	    }
-          case 's': {
-	        char ch;
-
-		if (count == 1) count = 256;
-                while (count--)
-                {
-                    if (!DEBUG_READ_MEM_VERBOSE(pnt, &ch, sizeof(ch)) || !ch)
-		       break;
-                    pnt++;
-                    DEBUG_Output(DBG_CHN_MESG, &ch, 1);
-                }
-		DEBUG_Printf(DBG_CHN_MESG,"\n");
+        case 's':
+                DEBUG_nchar += DEBUG_PrintStringA(DBG_CHN_MESG, &value.addr, count);
+		DEBUG_Printf(DBG_CHN_MESG, "\n");
 		return;
-	  }
 	case 'i':
 		while (count-- && DEBUG_DisassembleInstruction( &value.addr ));
 		return;
@@ -329,4 +311,51 @@
         case 'c': DO_DUMP2(char, 32, " %c", (_v < 0x20) ? ' ' : _v);
 	case 'b': DO_DUMP2(char, 16, " %02x", (_v) & 0xff);
 	}
+}
+
+/******************************************************************
+ *		DEBUG_PrintStringA
+ *
+ * Prints on channel chnl, the string starting at address in target
+ * address space. The string stops when either len chars (if <> -1)
+ * have been printed, or the '\0' char is printed
+ */
+int  DEBUG_PrintStringA(int chnl, const DBG_ADDR* address, int len)
+{
+    char*       lin = (void*)DEBUG_ToLinear(address);
+    char        ach[16+1];
+    int         i, l;
+
+    if (len == -1) len = 32767; /* should be big enough */
+
+    /* so that the ach is always terminated */
+    ach[sizeof(ach) - 1] = '\0';
+    for (i = len; i >= 0; i -= sizeof(ach) - 1)
+    {
+        l = min(sizeof(ach) - 1, i);
+        DEBUG_READ_MEM_VERBOSE(lin, ach, l);
+        l = strlen(ach);
+        DEBUG_OutputA(chnl, ach, l);
+        lin += l;
+        if (l < sizeof(ach) - 1) break;
+    }
+    return len - i; /* number of actually written chars */
+}
+
+int  DEBUG_PrintStringW(int chnl, const DBG_ADDR* address, int len)
+{
+    char*       lin = (void*)DEBUG_ToLinear(address);
+    WCHAR       wch;
+    int         ret = 0;
+
+    if (len == -1) len = 32767; /* should be big enough */
+    while (len--)
+    {
+        if (!DEBUG_READ_MEM_VERBOSE(lin, &wch, sizeof(wch)) || !wch)
+            break;
+        lin += sizeof(wch);
+        DEBUG_OutputW(chnl, &wch, 1);
+        ret++;
+    }
+    return ret;
 }
Index: debugger/types.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/debugger/types.c,v
retrieving revision 1.28
diff -u -u -r1.28 types.c
--- debugger/types.c	9 Mar 2002 23:50:37 -0000	1.28
+++ debugger/types.c	26 Apr 2002 04:29:02 -0000
@@ -875,7 +875,6 @@
       size = DEBUG_GetObjectSize(value->type->un.array.basictype);
       if( size == 1 )
 	{
-          char  ach[16];
           int   len, clen;
 
 	  /*
@@ -883,21 +882,17 @@
 	   */
 	  pnt = (char *) value->addr.off;
           len = value->type->un.array.end - value->type->un.array.start + 1;
-          clen = (DEBUG_nchar + len < DEBUG_maxchar) 
+          clen = (DEBUG_nchar + len < DEBUG_maxchar)
               ? len : (DEBUG_maxchar - DEBUG_nchar);
 
           DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "\"");
           switch (value->cookie)
           {
           case DV_TARGET:
-              for (i = clen; i > 0; i -= sizeof(ach))
-              {
-                  DEBUG_READ_MEM(pnt, ach, min(sizeof(ach), i));
-                  DEBUG_Output(DBG_CHN_MESG, ach, min(sizeof(ach), i));
-              }
+              clen = DEBUG_PrintStringA(DBG_CHN_MESG, &value->addr, clen);
               break;
           case DV_HOST:
-              DEBUG_Output(DBG_CHN_MESG, pnt, clen);
+              DEBUG_OutputA(DBG_CHN_MESG, pnt, clen);
               break;
           default: assert(0);
           }
Index: debugger/winedbg.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/debugger/winedbg.c,v
retrieving revision 1.51
diff -u -u -r1.51 winedbg.c
--- debugger/winedbg.c	11 May 2002 23:06:32 -0000	1.51
+++ debugger/winedbg.c	25 May 2002 13:51:51 -0000
@@ -48,7 +48,7 @@
 static int automatic_mode;
 DBG_INTVAR DEBUG_IntVars[DBG_IV_LAST];
 
-void	DEBUG_Output(int chn, const char* buffer, int len)
+void	DEBUG_OutputA(int chn, const char* buffer, int len)
 {
     if (DBG_IVAR(ConChannelMask) & chn)
 	WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL);
@@ -56,6 +56,16 @@
 	fwrite(buffer, len, 1, stderr);
 }
 
+void	DEBUG_OutputW(int chn, const WCHAR* buffer, int len)
+{
+    /* FIXME: this won't work is std output isn't attached to a console */
+    if (DBG_IVAR(ConChannelMask) & chn)
+	WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL);
+    /* simplistic Unicode to ANSI conversion */
+    if (DBG_IVAR(StdChannelMask) & chn)
+        while (len--) fputc((char)*buffer++, stderr);
+}
+
 int	DEBUG_Printf(int chn, const char* format, ...)
 {
 static    char	buf[4*1024];
@@ -71,7 +81,7 @@
 	buf[len] = 0;
 	buf[len - 1] = buf[len - 2] = buf[len - 3] = '.';
     }
-    DEBUG_Output(chn, buf, len);
+    DEBUG_OutputA(chn, buf, len);
     return len;
 }
 
Index: debugger/debugger.h
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/debugger/debugger.h,v
retrieving revision 1.31
diff -u -u -r1.31 debugger.h
--- debugger/debugger.h	1 Apr 2002 21:03:13 -0000	1.31
+++ debugger/debugger.h	21 Apr 2002 19:09:32 -0000
@@ -419,6 +419,8 @@
 extern void DEBUG_FixAddress( DBG_ADDR *address, DWORD def );
 extern int  DEBUG_IsSelectorSystem( WORD sel );
 #endif
+extern int  DEBUG_PrintStringA( int chnl, const DBG_ADDR* address, int len );
+extern int  DEBUG_PrintStringW( int chnl, const DBG_ADDR* address, int len );
 
   /* debugger/module.c */
 extern int  DEBUG_LoadEntryPoints( const char * prefix );
@@ -513,7 +515,8 @@
 #define DBG_CHN_WARN	4
 #define DBG_CHN_FIXME	8
 #define DBG_CHN_TRACE	16
-extern void	DEBUG_Output(int chn, const char* buffer, int len);
+extern void	DEBUG_OutputA(int chn, const char* buffer, int len);
+extern void	DEBUG_OutputW(int chn, const WCHAR* buffer, int len);
 #ifdef __GNUC__
 extern int	DEBUG_Printf(int chn, const char* format, ...) __attribute__((format (printf,2,3)));           
 #else


More information about the wine-patches mailing list