debugger update for new console

eric pouech eric.pouech at wanadoo.fr
Sun Nov 4 16:14:26 CST 2001


because the debugger was using some undocumented features
of the old console interface (and was implementing some console
features too), some update was needed. here it is.

PS1: file debugger/editline.c is now obsolete.
PS2: apply the caret and the console patch before this one.

A+
-- 
---------------
Eric Pouech (http://perso.wanadoo.fr/eric.pouech/)
"The future will be better tomorrow", Vice President Dan Quayle
-------------- next part --------------
Name: wnc_dbg
ChangeLog: revisited console support (got rid of old hacks and private editline since we now have a brand new console), removed private debug heap
GenDate: 2001/11/04 20:42:30 UTC
ModifiedFiles: debugger/Makefile.in debugger/debug.l debugger/debugger.h debugger/hash.c debugger/source.c debugger/winedbg.c
AddedFiles: 
===================================================================
RCS file: /usr/share/cvs/cvsroot/wine/wine/debugger/Makefile.in,v
retrieving revision 1.24
diff -u -u -r1.24 Makefile.in
--- debugger/Makefile.in	2000/12/29 05:38:00	1.24
+++ debugger/Makefile.in	2001/09/30 19:59:51
@@ -9,7 +9,6 @@
 	break.c \
 	db_disasm.c \
 	display.c \
-	editline.c \
 	expr.c \
 	ext_debugger.c \
 	hash.c \
Index: debugger/debug.l
===================================================================
RCS file: /usr/share/cvs/cvsroot/wine/wine/debugger/debug.l,v
retrieving revision 1.20
diff -u -u -r1.20 debug.l
--- debugger/debug.l	2001/10/08 20:28:58	1.20
+++ debugger/debug.l	2001/10/09 04:28:25
@@ -8,17 +8,17 @@
 %{
 #include <stdlib.h>
 #include <string.h>
+#include "winbase.h"
+#include "wincon.h"
 #include "debugger.h"
 #include "y.tab.h"
 
 #ifndef DONT_USE_READLINE
 #undef YY_INPUT
 #define YY_INPUT(buf,result,max_size) \
-	if ( (result = dbg_read((char *) buf, max_size )) < 0 ) \
+	if ( (result = DEBUG_ReadLine("Wine-dbg>", (char *) buf, max_size, TRUE )) < 0 ) \
 	    YY_FATAL_ERROR( "read() in flex scanner failed" );
 
-static int dbg_read(char * buf, int size);
-
 #endif  /* DONT_USE_READLINE */
 
 #define YY_NO_UNPUT
@@ -195,52 +195,61 @@
   string[++i] = '\0';
 }
 
-static int dbg_read(char * buf, int size)
+int DEBUG_ReadLine(const char* pfx, char * buf, int size, int remind)
 {
-    static char last_line[256] = "";
-    char * line;
-    int len;
-    
+    char 	buf_line[256];
+    char*	ptr;
+    int 	len;
+    DWORD	nread;
+
     for (;;)
     {
         DEBUG_FlushSymbols();
-        line = readline ("Wine-dbg>");
-        if (!line)
-        {
-            DEBUG_Printf( DBG_CHN_MESG, "\n" );
-            DEBUG_Exit(0);
-        }
-
-        /* Remove leading and trailing whitespace from the line */
-
-        stripwhite (line);
+	WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), pfx, strlen(pfx), NULL, NULL);
 
-        /* If there is anything left, add it to the history list
-           and execute it. Otherwise, re-execute last command. */
+	if (!ReadConsole(GetStdHandle(STD_INPUT_HANDLE), buf_line, sizeof(buf_line), &nread, NULL))
+	    break;
+	/* FIXME: should be rewritten not to remove and then add the trailing '\n' */
+	if (nread > 0 && buf_line[nread - 1] == '\n') nread--;
+	buf_line[nread] = 0;
 
-        if (*line)
-        {
-            add_history( line );
-            strncpy( last_line, line, 255 );
-            last_line[255] = '\0'; 
-        }
+        /* Remove leading and trailing whitespace from the line */
+        stripwhite (buf_line);
 
-        free( line );
-        line = last_line;
+	if (remind)
+	{
+	    static char last_line[256] = "";
+	    /* If there is anything left, add it to the history list
+	       and execute it. Otherwise, re-execute last command. */
+	
+	    if (*buf_line)
+	    {
+		strncpy( last_line, buf_line, sizeof(last_line) - 1 );
+		last_line[sizeof(last_line) - 1] = '\0'; 
+	    }
+	    ptr = last_line;
+	}
+	else
+	{
+	    /* I could also tweak with the undoc functions to remove this line from the console
+	     * history... */
+	    ptr = buf_line;
+	}
 
-        if ((len = strlen(line)) > 0)
+        if ((len = strlen(ptr)) > 0)
         {
-            if (size < len + 1)
+	    if (size < len + 1)
             {
-                DEBUG_Printf(DBG_CHN_MESG,"Fatal readline goof.\n");
+		DEBUG_Printf(DBG_CHN_MESG, "Fatal readline goof.\n");
 		DEBUG_Exit(0);
             }
-            strcpy(buf, line);
+            strcpy(buf, ptr);
             buf[len] = '\n';
             buf[len+1] = 0;
             return len + 1;
         }
     }
+    return 0;
 }
 
 static char *local_symbols[30];
Index: debugger/debugger.h
===================================================================
RCS file: /usr/share/cvs/cvsroot/wine/wine/debugger/debugger.h,v
retrieving revision 1.25
diff -u -u -r1.25 debugger.h
--- debugger/debugger.h	2001/08/15 17:40:31	1.25
+++ debugger/debugger.h	2001/10/13 18:50:42
@@ -287,6 +287,7 @@
   /* debugger/debug.l */
 extern void DEBUG_FlushSymbols(void);
 extern char*DEBUG_MakeSymbol(const char*);
+extern int  DEBUG_ReadLine(const char* pfx, char* buffer, int size, int remind);
 
   /* debugger/display.c */
 extern int DEBUG_DoDisplay(void);
@@ -512,13 +513,11 @@
 #define DBG_strdup(x) 		DEBUG_XStrDup(x)
 #else
 /* this one is slow (takes 5 minutes to load the debugger on my machine),
-   but is pretty crash-proof (can step through malloc() without problems,
-   malloc() arena (and other heaps) can be totally wasted and it'll still
-   work, etc... if someone could make optimized routines so it wouldn't
+   if someone could make optimized routines so it wouldn't
    take so long to load, it could be made default) */
-#define DBG_alloc(x) HeapAlloc(dbg_heap,0,x)
-#define DBG_realloc(x,y) HeapRealloc(dbg_heap,0,x,y)
-#define DBG_free(x) HeapFree(dbg_heap,0,x)
+#define DBG_alloc(x) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,x)
+#define DBG_realloc(x,y) HeapReAlloc(GetProcessHeap(),0,x,y)
+#define DBG_free(x) HeapFree(GetProcessHeap(),0,x)
 inline static LPSTR DBG_strdup( LPCSTR str )
 {
     INT len = strlen(str) + 1;
@@ -526,8 +525,6 @@
     if (p) memcpy( p, str, len );
     return p;
 }
-#define DBG_need_heap
-extern HANDLE dbg_heap;
 #endif
 
 #define	DEBUG_STATUS_OFFSET		0x80003000
Index: debugger/hash.c
===================================================================
RCS file: /usr/share/cvs/cvsroot/wine/wine/debugger/hash.c,v
retrieving revision 1.24
diff -u -u -r1.24 hash.c
--- debugger/hash.c	2001/10/08 22:16:06	1.24
+++ debugger/hash.c	2001/10/09 04:28:26
@@ -387,7 +387,8 @@
    } else if (!DEBUG_interactiveP || num == 1) {
       i = 0;
    } else {
-      char*	ptr;
+      char	buffer[256];
+
       if (num == NUMDBGV+1) {
 	 DEBUG_Printf(DBG_CHN_MESG, "Too many addresses for symbol '%s', limiting the first %d\n", name, NUMDBGV);
 	 num = NUMDBGV;
@@ -399,11 +400,13 @@
 	 DEBUG_Printf(DBG_CHN_MESG, "\n");
       }
       do {
-	 ptr = readline("=> ");
-	 if (!*ptr) return FALSE;
-	 i = atoi(ptr);
-	 if (i < 1 || i > num)
-	     DEBUG_Printf(DBG_CHN_MESG, "Invalid choice %d\n", i);
+	  i = 0;
+	  if (DEBUG_ReadLine("=> ", buffer, sizeof(buffer), FALSE))
+	  {
+	      i = atoi(buffer);
+	      if (i < 1 || i > num)
+		  DEBUG_Printf(DBG_CHN_MESG, "Invalid choice %d\n", i);
+	  }
       } while (i < 1 || i > num);
 
       /* The array is 0-based, but the choices are 1..n, so we have to subtract one before returning. */
Index: debugger/source.c
===================================================================
RCS file: /usr/share/cvs/cvsroot/wine/wine/debugger/source.c,v
retrieving revision 1.16
diff -u -u -r1.16 source.c
--- debugger/source.c	2000/07/25 12:51:56	1.16
+++ debugger/source.c	2001/09/30 20:00:55
@@ -188,7 +188,7 @@
 	       * Still couldn't find it.  Ask user for path to add.
 	       */
 	      sprintf(zbuf, "Enter path to file '%s': ", sourcefile);
-	      lstrcpynA(tmppath, readline(zbuf), sizeof(tmppath));
+	      DEBUG_ReadLine(zbuf, tmppath, sizeof(tmppath), FALSE);
 	      
 	      if( tmppath[strlen(tmppath)-1] == '\n' )
 		{
Index: debugger/winedbg.c
===================================================================
RCS file: /usr/share/cvs/cvsroot/wine/wine/debugger/winedbg.c,v
retrieving revision 1.42
diff -u -u -r1.42 winedbg.c
--- debugger/winedbg.c	2001/10/22 19:00:34	1.42
+++ debugger/winedbg.c	2001/11/04 19:46:21
@@ -19,10 +19,6 @@
 
 #include "winreg.h"
 
-#ifdef DBG_need_heap
-HANDLE dbg_heap = 0;
-#endif
-
 DBG_PROCESS*	DEBUG_CurrProcess = NULL;
 DBG_THREAD*	DEBUG_CurrThread = NULL;
 DWORD		DEBUG_CurrTid;
@@ -464,6 +460,9 @@
         case EXCEPTION_DATATYPE_MISALIGNMENT:
             DEBUG_Printf(DBG_CHN_MESG, "Alignment");
             break;
+	case DBG_CONTROL_C:
+            DEBUG_Printf(DBG_CHN_MESG, "^C");
+            break;
         case CONTROL_C_EXIT:
             DEBUG_Printf(DBG_CHN_MESG, "^C");
             break;
@@ -863,7 +862,7 @@
     startup.wShowWindow = SW_SHOWNORMAL;
     
     if (!CreateProcess(NULL, cmdLine, NULL, NULL, 
-		       FALSE, DEBUG_PROCESS, NULL, NULL, &startup, &info)) {
+		       FALSE, DEBUG_PROCESS|DETACHED_PROCESS, NULL, NULL, &startup, &info)) {
 	DEBUG_Printf(DBG_CHN_MESG, "Couldn't start process '%s'\n", cmdLine);
 	return FALSE;
     }
@@ -889,15 +921,41 @@
     }
 }
 
+static void DEBUG_InitConsole(void)
+{
+    COORD	c;
+    SMALL_RECT	sr;
+    DWORD	mode;
+
+    /* keep it as a cuiexe for now, so that Wine won't touch the Unix stdin, 
+     * stdout and stderr streams
+     */
+    if (DBG_IVAR(UseXTerm)) 
+    {
+	FreeConsole();
+	AllocConsole();
+    }
+    /* this would be nicer for output */
+    c.X = 132;
+    c.Y = 500;
+    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), c);
+
+    /* sets the console's window width accordingly */
+    sr.Left   = 0;
+    sr.Top    = 0;
+    sr.Right  = c.X - 1;
+    sr.Bottom = 50;
+    SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &sr);
+
+    /* put the line editing mode with the nice emacs features (FIXME: could be triggered by a IVAR) */
+    if (GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode))
+	SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode | ENABLE_LINE_INPUT_EMACS);
+}
+
 int DEBUG_main(int argc, char** argv)
 {
     DWORD	retv = 0;
 
-#ifdef DBG_need_heap
-    /* Initialize the debugger heap. */
-    dbg_heap = HeapCreate(HEAP_NO_SERIALIZE, 0x1000, 0x8000000); /* 128MB */
-#endif
-    
     /* Initialize the type handling stuff. */
     DEBUG_InitTypes();
     DEBUG_InitCVDataTypes();    
@@ -917,17 +975,8 @@
         DBG_IVAR(StdChannelMask) = DBG_CHN_MESG;
     }
 
-    /* keep it as a guiexe for now, so that Wine won't touch the Unix stdin, 
-     * stdout and stderr streams
-     */
-    if (DBG_IVAR(UseXTerm)) {
-	COORD		pos;
-	
-	/* This is a hack: it forces creation of an xterm, not done by default */
-	pos.X = 0; pos.Y = 1;
-	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
-    }
-
+    DEBUG_InitConsole();
+    
     DEBUG_Printf(DBG_CHN_MESG, "WineDbg starting... ");
 	
     if (argc == 3) {


More information about the wine-patches mailing list