detaching debugger

Eric Pouech eric.pouech at wanadoo.fr
Sat Feb 23 15:58:45 CST 2002


since we can now detach the debugger, the detach command has been added
to the wine debugger
however, because of some debugger internals (like symbols are globally
handled and are not freed on process deletion), the detach command will
also exit the debugger (but the debuggee will keep on running)
I might fix it in a while

A+
-------------- next part --------------
Name: wdbg_detach
ChangeLog: added the detach command to the debugger
GenDate: 2002/02/23 21:35:12 UTC
ModifiedFiles: debugger/dbg.y debugger/debug.l debugger/debugger.h debugger/winedbg.c documentation/debugger.sgml
AddedFiles: 
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/debugger/dbg.y,v
retrieving revision 1.48
diff -u -u -r1.48 dbg.y
--- debugger/dbg.y	4 Feb 2002 18:40:40 -0000	1.48
+++ debugger/dbg.y	6 Feb 2002 19:15:13 -0000
@@ -46,7 +46,7 @@
 %token <string> tPATH
 %token <string> tIDENTIFIER tSTRING tDEBUGSTR tINTVAR
 %token <integer> tNUM tFORMAT
-%token tSYMBOLFILE tRUN tATTACH tNOPROCESS
+%token tSYMBOLFILE tRUN tATTACH tDETACH tNOPROCESS
 
 %token tCHAR tSHORT tINT tLONG tFLOAT tDOUBLE tUNSIGNED tSIGNED 
 %token tSTRUCT tUNION tENUM
@@ -88,31 +88,31 @@
     | error tEOL               	{ yyerrok; }
 
 command:
-      tQUIT tEOL		{ return FALSE; }
+      tQUIT tEOL		{ return EXIT_QUIT; }
     | tHELP tEOL                { DEBUG_Help(); }
     | tHELP tINFO tEOL          { DEBUG_HelpInfo(); }
     | tCONT tEOL                { DEBUG_CurrThread->dbg_exec_count = 1; 
-				  DEBUG_CurrThread->dbg_exec_mode = EXEC_CONT; return TRUE; }
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_CONT; return EXIT_CONT; }
     | tPASS tEOL                { DEBUG_CurrThread->dbg_exec_count = 1; 
-				  DEBUG_CurrThread->dbg_exec_mode = EXEC_PASS; return TRUE; }
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_PASS; return EXIT_CONT; }
     | tCONT tNUM tEOL         	{ DEBUG_CurrThread->dbg_exec_count = $2; 
-				  DEBUG_CurrThread->dbg_exec_mode = EXEC_CONT; return TRUE; }
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_CONT; return EXIT_CONT; }
     | tSTEP tEOL               	{ DEBUG_CurrThread->dbg_exec_count = 1; 
-				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_INSTR; return TRUE; }
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_INSTR; return EXIT_CONT; }
     | tNEXT tEOL                { DEBUG_CurrThread->dbg_exec_count = 1; 
-				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_OVER; return TRUE; }
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_OVER; return EXIT_CONT; }
     | tSTEP tNUM tEOL           { DEBUG_CurrThread->dbg_exec_count = $2; 
-				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_INSTR; return TRUE; }
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_INSTR; return EXIT_CONT; }
     | tNEXT tNUM tEOL           { DEBUG_CurrThread->dbg_exec_count = $2; 
-				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_OVER; return TRUE; }
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_OVER; return EXIT_CONT; }
     | tSTEPI tEOL               { DEBUG_CurrThread->dbg_exec_count = 1; 
-				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_INSTR; return TRUE; }
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_INSTR; return EXIT_CONT; }
     | tNEXTI tEOL               { DEBUG_CurrThread->dbg_exec_count = 1; 
-				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_OVER; return TRUE; }
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_OVER; return EXIT_CONT; }
     | tSTEPI tNUM tEOL          { DEBUG_CurrThread->dbg_exec_count = $2; 
-			 	  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_INSTR; return TRUE; }
+			 	  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_INSTR; return EXIT_CONT; }
     | tNEXTI tNUM tEOL          { DEBUG_CurrThread->dbg_exec_count = $2; 
-                                  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_OVER; return TRUE; }
+                                  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_OVER; return EXIT_CONT; }
     | tABORT tEOL              	{ kill(getpid(), SIGABRT); }
     | tMODE tNUM tEOL          	{ mode_command($2); }
     | tMODE tVM86 tEOL         	{ DEBUG_CurrThread->dbg_mode = MODE_VM86; }
@@ -127,7 +127,7 @@
     | tDOWN tNUM tEOL	       	{ DEBUG_SetFrame( curr_frame - $2 ); }
     | tFRAME tNUM tEOL         	{ DEBUG_SetFrame( $2 ); }
     | tFINISH tEOL	       	{ DEBUG_CurrThread->dbg_exec_count = 0;
-				  DEBUG_CurrThread->dbg_exec_mode = EXEC_FINISH; return TRUE; }
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_FINISH; return EXIT_CONT; }
     | tSHOW tDIR tEOL	       	{ DEBUG_ShowDir(); }
     | tDIR pathname tEOL       	{ DEBUG_AddPath( $2 ); }
     | tDIR tEOL		       	{ DEBUG_NukePath(); }
@@ -142,7 +142,8 @@
     | tCOND tNUM expr tEOL	{ DEBUG_AddBPCondition($2, $3); }
     | tSYMBOLFILE pathname tEOL	{ DEBUG_ReadSymbolTable($2); }
     | tWHATIS expr_addr tEOL	{ DEBUG_PrintType(&$2); DEBUG_FreeExprMem(); }
-    | tATTACH tNUM tEOL		{ if (DEBUG_Attach($2, FALSE)) return TRUE; }
+    | tATTACH tNUM tEOL		{ if (DEBUG_Attach($2, FALSE)) return EXIT_CONT; }
+    | tDETACH tEOL              { return EXIT_DETACH; }
     | list_command
     | disassemble_command
     | set_command
@@ -390,10 +391,10 @@
  *
  * Debugger editline parser
  */
-BOOL	DEBUG_Parser(void)
+enum exit_mode	DEBUG_Parser(void)
 {
-    BOOL 	ret_ok;
-    BOOL	ret = TRUE;
+    BOOL 	        ret_ok;
+    enum exit_mode	ret = EXIT_CONT;
 #ifdef YYDEBUG
     yydebug = 0;
 #endif
Index: debugger/debug.l
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/debugger/debug.l,v
retrieving revision 1.23
diff -u -u -r1.23 debug.l
--- debugger/debug.l	4 Feb 2002 18:40:40 -0000	1.23
+++ debugger/debug.l	6 Feb 2002 19:04:31 -0000
@@ -117,6 +117,7 @@
 <INITIAL>watch|watc|wat			{ BEGIN(NOCMD); return tWATCH; }
 <INITIAL>whatis|whati|what		{ BEGIN(NOCMD); return tWHATIS; }
 <INITIAL,NOPROCESS>run|ru|r     	{ BEGIN(ASTRING_EXPECTED); return tRUN;}
+<INITIAL>detach|detac|deta|det   	{ BEGIN(NOCMD); return tDETACH; }
 <NOPROCESS>attach|attac|atta|att 	{ BEGIN(NOCMD); return tATTACH; }
 <INFO_CMD>share|shar|sha		{ return tSHARE; }
 <INFO_CMD>locals|local|loca|loc		{ return tLOCAL; }
Index: debugger/debugger.h
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/debugger/debugger.h,v
retrieving revision 1.28
diff -u -u -r1.28 debugger.h
--- debugger/debugger.h	4 Feb 2002 18:40:40 -0000	1.28
+++ debugger/debugger.h	6 Feb 2002 19:04:31 -0000
@@ -157,6 +157,10 @@
 };
 
 
+enum exit_mode
+{
+    EXIT_CONT, EXIT_QUIT, EXIT_DETACH
+};
 
 /* Wine extension; Windows doesn't have a name for this code.  This is an
    undocumented exception understood by MS VC debugger, allowing the program
@@ -287,7 +291,7 @@
 extern void DEBUG_Disasm( DBG_ADDR *addr, int display );
 
   /* debugger/dbg.y */
-extern BOOL DEBUG_Parser(void);
+extern enum exit_mode DEBUG_Parser(void);
 extern void DEBUG_Exit( DWORD );
 
   /* debugger/debug.l */
@@ -502,6 +506,7 @@
 #endif
 extern DBG_INTVAR*	DEBUG_GetIntVar(const char*);
 extern BOOL DEBUG_Attach(DWORD pid, BOOL cofe);
+extern BOOL DEBUG_Detach(void);
 extern void DEBUG_Run(const char* args);
 extern DBG_PROCESS* 	DEBUG_GetProcess(DWORD pid);
 extern DBG_THREAD* 	DEBUG_GetThread(DBG_PROCESS* p, DWORD tid);
Index: debugger/winedbg.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/debugger/winedbg.c,v
retrieving revision 1.46
diff -u -u -r1.46 winedbg.c
--- debugger/winedbg.c	29 Jan 2002 03:12:20 -0000	1.46
+++ debugger/winedbg.c	20 Feb 2002 21:33:01 -0000
@@ -284,6 +284,23 @@
     return TRUE;
 }
 
+BOOL				DEBUG_Detach(void)
+{
+    /* remove all set breakpoints in debuggee code */
+    DEBUG_SetBreakpoints(FALSE);
+    /* needed for single stepping (ugly). 
+     * should this be handled inside the server ??? */
+#ifdef __i386__
+    DEBUG_context.EFlags &= ~STEP_FLAG;
+#endif
+    SetThreadContext(DEBUG_CurrThread->handle, &DEBUG_context);
+    DebugActiveProcessStop(DEBUG_CurrProcess->pid);
+    DEBUG_DelProcess(DEBUG_CurrProcess);
+    DEBUG_CurrProcess = NULL;
+    /* FIXME: should zero out the symbol table too */
+    return TRUE;
+}
+
 static  BOOL	DEBUG_ExceptionProlog(BOOL is_debug, BOOL force, DWORD code)
 {
     DBG_ADDR	addr;
@@ -386,10 +403,10 @@
     return (DEBUG_CurrThread->dbg_exec_mode == EXEC_PASS) ? DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
 }
 
-static	BOOL	DEBUG_HandleException(EXCEPTION_RECORD *rec, BOOL first_chance, BOOL force, LPDWORD cont)
+static	enum exit_mode DEBUG_HandleException(EXCEPTION_RECORD *rec, BOOL first_chance, BOOL force, LPDWORD cont)
 {
     BOOL             is_debug = FALSE;
-    BOOL             ret = TRUE;
+    enum exit_mode   ret = EXIT_CONT;
     THREADNAME_INFO *pThreadName;
     DBG_THREAD      *pThread;
 
@@ -414,14 +431,14 @@
             DEBUG_Printf (DBG_CHN_MESG,
                           "Thread ID=0x%lx renamed using MS VC6 extension (name==\"%s\")\n",
                           pThread->tid, pThread->name);
-        return TRUE;
+        return EXIT_CONT;
     }
 
     if (first_chance && !is_debug && !force && !DBG_IVAR(BreakOnFirstChance))
     {
         /* pass exception to program except for debug exceptions */
         *cont = is_debug ? DBG_CONTINUE : DBG_EXCEPTION_NOT_HANDLED;
-        return TRUE;
+        return EXIT_CONT;
     }
 
     if (!is_debug)
@@ -479,7 +496,7 @@
 	    if (!DBG_IVAR(BreakOnCritSectTimeOut))
 	    {
 		DEBUG_Printf(DBG_CHN_MESG, "\n");
-		return TRUE;
+		return EXIT_CONT;
 	    }
             break;
         case EXCEPTION_WINE_STUB:
@@ -522,12 +539,12 @@
     if (automatic_mode)
     {
         DEBUG_ExceptionProlog(is_debug, FALSE, rec->ExceptionCode);
-        return FALSE;  /* terminate execution */
+        return EXIT_QUIT;  /* terminate execution */
     }
 
     if (DEBUG_ExceptionProlog(is_debug, force, rec->ExceptionCode)) {
 	DEBUG_interactiveP = TRUE;
-	while ((ret = DEBUG_Parser())) {
+	while ((ret = DEBUG_Parser()) == EXIT_CONT) {
 	    if (DEBUG_ValidateRegisters()) {
 		if (DEBUG_CurrThread->dbg_exec_mode != EXEC_PASS || first_chance)
 		    break;
@@ -555,13 +572,13 @@
 static	BOOL	DEBUG_HandleDebugEvent(DEBUG_EVENT* de, LPDWORD cont)
 {
     char		buffer[256];
-    BOOL		ret;
+    enum exit_mode      ret;
 
     DEBUG_CurrPid = de->dwProcessId;
     DEBUG_CurrTid = de->dwThreadId;
 
     __TRY {
-	ret = TRUE;
+	ret = EXIT_CONT;
 	*cont = 0L;
 	
 	if ((DEBUG_CurrProcess = DEBUG_GetProcess(de->dwProcessId)) != NULL)
@@ -798,7 +815,7 @@
 	
     } __EXCEPT(wine_dbg) {
 	*cont = 0;
-	ret = TRUE;
+	ret = EXIT_CONT;
     }
     __ENDTRY;
     return ret;
@@ -808,20 +825,29 @@
 {
     DEBUG_EVENT		de;
     DWORD		cont;
-    BOOL		ret;
+    enum exit_mode      ret = EXIT_CONT;
 
     DEBUG_Printf(DBG_CHN_MESG, " on pid %lx\n", DEBUG_CurrPid);
     
-    for (ret = TRUE; ret; ) {
+    while (ret == EXIT_CONT) 
+    {
 	/* wait until we get at least one loaded process */
-	while (!DEBUG_ProcessList && (ret = DEBUG_Parser()));
-	if (!ret) break;
+	while (!DEBUG_ProcessList && (ret = DEBUG_Parser()) == EXIT_CONT);
+	if (ret != EXIT_CONT) break;
 
-	while (ret && DEBUG_ProcessList && WaitForDebugEvent(&de, INFINITE)) {
+	while (ret == EXIT_CONT && DEBUG_ProcessList && WaitForDebugEvent(&de, INFINITE)) {
 	    ret = DEBUG_HandleDebugEvent(&de, &cont);
 	    ContinueDebugEvent(de.dwProcessId, de.dwThreadId, cont);
 	}
-    };
+        if (ret == EXIT_DETACH && DEBUG_Detach())
+        {
+            /* ret = EXIT_CONT; */
+            /* FIXME: as we don't have a simple way to zero out the process symbol table
+             * we simply quit the debugger on detach...
+             */
+            ret = EXIT_QUIT;
+        }
+    }
     
     DEBUG_Printf(DBG_CHN_MESG, "WineDbg terminated on pid %lx\n", DEBUG_CurrPid);
 
@@ -832,11 +858,11 @@
 {
     DEBUG_EVENT de;
     DWORD cont;
-    BOOL ret = TRUE;
+    enum exit_mode ret = EXIT_CONT;
 
     DEBUG_Printf(DBG_CHN_MESG, " on pid %lx\n", DEBUG_CurrPid);
 
-    while (ret && DEBUG_ProcessList && WaitForDebugEvent(&de, INFINITE))
+    while (ret == EXIT_CONT && DEBUG_ProcessList && WaitForDebugEvent(&de, INFINITE))
     {
         ret = DEBUG_HandleDebugEvent(&de, &cont);
         ContinueDebugEvent(de.dwProcessId, de.dwThreadId, cont);
@@ -902,6 +928,7 @@
 	FreeConsole();
 	AllocConsole();
     }
+
     /* this would be nicer for output */
     c.X = 132;
     c.Y = 500;
Index: documentation/debugger.sgml
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/documentation/debugger.sgml,v
retrieving revision 1.9
diff -u -u -r1.9 debugger.sgml
--- documentation/debugger.sgml	12 Jan 2002 21:15:36 -0000	1.9
+++ documentation/debugger.sgml	20 Feb 2002 21:38:15 -0000
@@ -1281,6 +1281,8 @@
 
 attach N	attach to a W-process (N is its ID). IDs can be
 		obtained using the walk process command
+detach          detach from a W-process. WineDbg will exit (this may
+                be changed later on)
         </screen>
         <screen>
 help		prints some help on the commands


More information about the wine-patches mailing list