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