- cleaned-up break handling
- better integration of debugger inner loops (parser & events)
- added attach command
- improved parser so that it can be entered without any process loaded
- added BreakOnFirstChance internal variable
- disabled NE module symbol module (which is broken with ASS)
- misc portability cleanups

diff --git a/debugger/break.c b/debugger/break.c
index 7c00b59..2a1e4e9 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -369,6 +369,47 @@
     DEBUG_Printf( DBG_CHN_MESG, "\n" );
 }
 
+/***********************************************************************
+ *           DEBUG_AddBreakpointFromId
+ *
+ * Add a breakpoint from a function name (and eventually a line #)
+ */
+void	DEBUG_AddBreakpointFromId(const char *name, int lineno)
+{
+   DBG_VALUE value;
+   
+   if (DEBUG_GetSymbolValue(name, lineno, &value, TRUE))
+      DEBUG_AddBreakpoint(&value, NULL);
+   else
+      DEBUG_Printf(DBG_CHN_MESG, "Unable to add breakpoint\n");
+}
+
+/***********************************************************************
+ *           DEBUG_AddBreakpointFromLineno
+ *
+ * Add a breakpoint from a line number in current file
+ */
+void	DEBUG_AddBreakpointFromLineno(int lineno)
+{
+   DBG_VALUE 			value;
+   
+   DEBUG_GetCurrentAddress(&value.addr);
+   
+   if (lineno != -1) {
+      struct name_hash*	nh;
+      
+      DEBUG_FindNearestSymbol(&value.addr, TRUE, &nh, 0, NULL);
+      if (nh == NULL) {
+	 DEBUG_Printf(DBG_CHN_MESG,"Unable to add breakpoint\n");
+	 return;
+      }
+      DEBUG_GetLineNumberAddr(nh, lineno, &value.addr, TRUE);
+   }
+   
+   value.type = NULL;
+   value.cookie = DV_TARGET;
+   DEBUG_AddBreakpoint( &value, NULL );
+}
 
  /***********************************************************************
  *           DEBUG_AddWatchpoint
@@ -439,6 +480,21 @@
 }
 
 /***********************************************************************
+ *           DEBUG_AddWathpointFromId
+ *
+ * Add a watchpoint from a symbol name (and eventually a line #)
+ */
+void	DEBUG_AddWatchpointFromId(const char *name, int lineno)
+{
+   DBG_VALUE value;
+   
+   if( DEBUG_GetSymbolValue(name, lineno, &value, TRUE) )
+      DEBUG_AddWatchpoint( &value, 1 );
+   else
+      DEBUG_Printf(DBG_CHN_MESG, "Unable to add watchpoint\n");
+}
+
+/***********************************************************************
  *           DEBUG_DelBreakpoint
  *
  * Delete a breakpoint.
@@ -921,8 +977,6 @@
         DEBUG_context.EFlags |= STEP_FLAG;
 #endif
         break;
-    case EXEC_KILL:
-        break;
     default:
         RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
     }
diff --git a/debugger/dbg.y b/debugger/dbg.y
index 7d1fdde..4d93dda 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -21,7 +21,6 @@
 #include "task.h"
 
 extern FILE * yyin;
-int curr_frame = 0;
 
 static void issue_prompt(void);
 static void mode_command(int);
@@ -37,20 +36,19 @@
     int              integer;
     struct list_id   listing;
     struct expr *    expression;
-    struct datatype * type;
+    struct datatype* type;
 }
 
 %token tCONT tPASS tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tINFO tWALK tUP tDOWN
 %token tENABLE tDISABLE tBREAK tWATCH tDELETE tSET tMODE tPRINT tEXAM tABORT
 %token tCLASS tMAPS tMODULE tSTACK tSEGMENTS tREGS tWND tQUEUE tLOCAL
-%token tPROCESS tTHREAD tMODREF
-%token tEOL tSTRING tDEBUGSTR
+%token tPROCESS tTHREAD tMODREF tEOL
 %token tFRAME tSHARE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE
 %token tSTEPI tNEXTI tFINISH tSHOW tDIR tWHATIS
 %token <string> tPATH
 %token <string> tIDENTIFIER tSTRING tDEBUGSTR tINTVAR
 %token <integer> tNUM tFORMAT
-%token tSYMBOLFILE
+%token tSYMBOLFILE tRUN tATTACH tNOPROCESS
 
 %token tCHAR tSHORT tINT tLONG tFLOAT tDOUBLE tUNSIGNED tSIGNED 
 %token tSTRUCT tUNION tENUM
@@ -84,67 +82,67 @@
 
 %%
 
-input: line                    { issue_prompt(); }
-    | input line               { issue_prompt(); }
+input: line                   	{ issue_prompt(); }
+    | input line                { issue_prompt(); }
 
 line: command 
     | tEOL
-    | error tEOL               { yyerrok; }
+    | error tEOL               	{ yyerrok; }
 
 command:
-      tQUIT tEOL               { DEBUG_CurrThread->dbg_exec_count = 1; 
-				 DEBUG_CurrThread->dbg_exec_mode = EXEC_KILL; return 1; }
-    | 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 0; }
-    | tPASS tEOL               { DEBUG_CurrThread->dbg_exec_count = 1; 
-				 DEBUG_CurrThread->dbg_exec_mode = EXEC_PASS; return 0; }
-    | tCONT tNUM tEOL          { DEBUG_CurrThread->dbg_exec_count = $2; 
-				 DEBUG_CurrThread->dbg_exec_mode = EXEC_CONT; return 0; }
-    | tSTEP tEOL               { DEBUG_CurrThread->dbg_exec_count = 1; 
-				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
-    | tNEXT tEOL               { DEBUG_CurrThread->dbg_exec_count = 1; 
-				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_OVER; return 0; }
-    | tSTEP tNUM tEOL          { DEBUG_CurrThread->dbg_exec_count = $2; 
-				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
-    | tNEXT tNUM tEOL          { DEBUG_CurrThread->dbg_exec_count = $2; 
-				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_OVER; return 0; }
-    | tSTEPI tEOL              { DEBUG_CurrThread->dbg_exec_count = 1; 
-				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_INSTR; return 0; }
-    | tNEXTI tEOL              { DEBUG_CurrThread->dbg_exec_count = 1; 
-				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_OVER; return 0; }
-    | tSTEPI tNUM tEOL         { DEBUG_CurrThread->dbg_exec_count = $2; 
-				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_INSTR; return 0; }
-    | tNEXTI tNUM tEOL         { DEBUG_CurrThread->dbg_exec_count = $2; 
-				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_OVER; return 0; }
-    | tABORT tEOL              { kill(getpid(), SIGABRT); }
-    | tMODE tNUM tEOL          { mode_command($2); }
-    | tENABLE tNUM tEOL        { DEBUG_EnableBreakpoint( $2, TRUE ); }
-    | tDISABLE tNUM tEOL       { DEBUG_EnableBreakpoint( $2, FALSE ); }
-    | tDELETE tBREAK tNUM tEOL { DEBUG_DelBreakpoint( $3 ); }
-    | tBACKTRACE tEOL	       { DEBUG_BackTrace(TRUE); }
-    | tUP tEOL		       { DEBUG_SetFrame( curr_frame + 1 );  }
-    | tUP tNUM tEOL	       { DEBUG_SetFrame( curr_frame + $2 ); }
-    | tDOWN tEOL	       { DEBUG_SetFrame( curr_frame - 1 );  }
-    | 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 0; }
-    | tSHOW tDIR tEOL	       { DEBUG_ShowDir(); }
-    | tDIR pathname tEOL       { DEBUG_AddPath( $2 ); }
-    | tDIR tEOL		       { DEBUG_NukePath(); }
-    | tDISPLAY tEOL	       { DEBUG_InfoDisplay(); }
-    | tDISPLAY expr tEOL       { DEBUG_AddDisplay($2, 1, 0); }
-    | tDISPLAY tFORMAT expr tEOL { DEBUG_AddDisplay($3, $2 >> 8, $2 & 0xff); }
-    | tDELETE tDISPLAY tNUM tEOL { DEBUG_DelDisplay( $3 ); }
-    | tDELETE tDISPLAY tEOL    { DEBUG_DelDisplay( -1 ); }
-    | tUNDISPLAY tNUM tEOL     { DEBUG_DelDisplay( $2 ); }
-    | tUNDISPLAY tEOL          { DEBUG_DelDisplay( -1 ); }
-    | tCOND tNUM tEOL          { DEBUG_AddBPCondition($2, NULL); }
-    | tCOND tNUM expr tEOL     { DEBUG_AddBPCondition($2, $3); }
-    | tSYMBOLFILE pathname tEOL{ DEBUG_ReadSymbolTable($2); }
-    | tWHATIS expr_addr tEOL   { DEBUG_PrintType(&$2); DEBUG_FreeExprMem(); }
+      tQUIT tEOL		{ return FALSE; }
+    | 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; }
+    | tPASS tEOL                { DEBUG_CurrThread->dbg_exec_count = 1; 
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_PASS; return TRUE; }
+    | tCONT tNUM tEOL         	{ DEBUG_CurrThread->dbg_exec_count = $2; 
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_CONT; return TRUE; }
+    | tSTEP tEOL               	{ DEBUG_CurrThread->dbg_exec_count = 1; 
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_INSTR; return TRUE; }
+    | tNEXT tEOL                { DEBUG_CurrThread->dbg_exec_count = 1; 
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_OVER; return TRUE; }
+    | tSTEP tNUM tEOL           { DEBUG_CurrThread->dbg_exec_count = $2; 
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_INSTR; return TRUE; }
+    | tNEXT tNUM tEOL           { DEBUG_CurrThread->dbg_exec_count = $2; 
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_OVER; return TRUE; }
+    | tSTEPI tEOL               { DEBUG_CurrThread->dbg_exec_count = 1; 
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_INSTR; return TRUE; }
+    | tNEXTI tEOL               { DEBUG_CurrThread->dbg_exec_count = 1; 
+				  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_OVER; return TRUE; }
+    | tSTEPI tNUM tEOL          { DEBUG_CurrThread->dbg_exec_count = $2; 
+			 	  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_INSTR; return TRUE; }
+    | tNEXTI tNUM tEOL          { DEBUG_CurrThread->dbg_exec_count = $2; 
+                                  DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_OVER; return TRUE; }
+    | tABORT tEOL              	{ kill(getpid(), SIGABRT); }
+    | tMODE tNUM tEOL          	{ mode_command($2); }
+    | tENABLE tNUM tEOL        	{ DEBUG_EnableBreakpoint( $2, TRUE ); }
+    | tDISABLE tNUM tEOL       	{ DEBUG_EnableBreakpoint( $2, FALSE ); }
+    | tDELETE tBREAK tNUM tEOL 	{ DEBUG_DelBreakpoint( $3 ); }
+    | tBACKTRACE tEOL	       	{ DEBUG_BackTrace(TRUE); }
+    | tUP tEOL		       	{ DEBUG_SetFrame( curr_frame + 1 );  }
+    | tUP tNUM tEOL	       	{ DEBUG_SetFrame( curr_frame + $2 ); }
+    | tDOWN tEOL	       	{ DEBUG_SetFrame( curr_frame - 1 );  }
+    | 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; }
+    | tSHOW tDIR tEOL	       	{ DEBUG_ShowDir(); }
+    | tDIR pathname tEOL       	{ DEBUG_AddPath( $2 ); }
+    | tDIR tEOL		       	{ DEBUG_NukePath(); }
+    | tDISPLAY tEOL	       	{ DEBUG_InfoDisplay(); }
+    | tDISPLAY expr tEOL       	{ DEBUG_AddDisplay($2, 1, 0); }
+    | tDISPLAY tFORMAT expr tEOL{ DEBUG_AddDisplay($3, $2 >> 8, $2 & 0xff); }
+    | tDELETE tDISPLAY tNUM tEOL{ DEBUG_DelDisplay( $3 ); }
+    | tDELETE tDISPLAY tEOL    	{ DEBUG_DelDisplay( -1 ); }
+    | tUNDISPLAY tNUM tEOL     	{ DEBUG_DelDisplay( $2 ); }
+    | tUNDISPLAY tEOL          	{ DEBUG_DelDisplay( -1 ); }
+    | tCOND tNUM tEOL          	{ DEBUG_AddBPCondition($2, NULL); }
+    | 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		{ DEBUG_Attach($2, FALSE); return TRUE; }
     | list_command
     | disassemble_command
     | set_command
@@ -154,6 +152,8 @@
     | watch_command
     | info_command
     | walk_command
+    | run_command
+    | noprocess_state
 
 set_command:
       tSET lval_addr '=' expr_value tEOL   { DEBUG_WriteMemory( &$2, $4 );
@@ -180,83 +180,33 @@
     | pathname ':' tNUM	       { $$.sourcefile = $1; $$.line = $3; }
     | tIDENTIFIER	       { DEBUG_GetFuncInfo( & $$, NULL, $1); }
     | pathname ':' tIDENTIFIER { DEBUG_GetFuncInfo( & $$, $1, $3); }
-    | '*' expr_addr	       { DEBUG_FindNearestSymbol( & $2.addr, FALSE, NULL, 
-							0, & $$ ); 
- 					     DEBUG_FreeExprMem(); }
+    | '*' expr_addr	       { DEBUG_FindNearestSymbol( & $2.addr, FALSE, NULL, 0, & $$ ); 
+                                 DEBUG_FreeExprMem(); }
 
 x_command:
-      tEXAM expr_addr tEOL     { DEBUG_ExamineMemory( &$2, 1, 'x'); 
- 					     DEBUG_FreeExprMem(); }
+      tEXAM expr_addr tEOL     { DEBUG_ExamineMemory( &$2, 1, 'x'); DEBUG_FreeExprMem(); }
     | tEXAM tFORMAT expr_addr tEOL  { DEBUG_ExamineMemory( &$3, $2>>8, $2&0xff ); 
- 					     DEBUG_FreeExprMem(); }
+ 				      DEBUG_FreeExprMem(); }
 
 print_command:
-      tPRINT expr_addr tEOL    { DEBUG_Print( &$2, 1, 0, 0 ); 
- 					     DEBUG_FreeExprMem(); }
+      tPRINT expr_addr tEOL    { DEBUG_Print( &$2, 1, 0, 0 ); DEBUG_FreeExprMem(); }
     | tPRINT tFORMAT expr_addr tEOL { DEBUG_Print( &$3, $2 >> 8, $2 & 0xff, 0 ); 
- 					     DEBUG_FreeExprMem(); }
+ 				      DEBUG_FreeExprMem(); }
 
 break_command:
-      tBREAK '*' expr_addr tEOL { DEBUG_AddBreakpoint( &$3, NULL ); 
- 					     DEBUG_FreeExprMem(); }
-    | tBREAK tIDENTIFIER tEOL  { DBG_VALUE value;
-				 if( DEBUG_GetSymbolValue($2, -1, &value, TRUE) )
-				   {
-				     DEBUG_AddBreakpoint( &value, NULL );
-				   }
-				 else
-				   {
-				     DEBUG_Printf(DBG_CHN_MESG,"Unable to add breakpoint\n");
-				   }
-				}
-    | tBREAK tIDENTIFIER ':' tNUM tEOL  { DBG_VALUE value;
-				 if( DEBUG_GetSymbolValue($2, $4, &value, TRUE) )
-				   {
-				     DEBUG_AddBreakpoint( &value, NULL );
-				   }
-				 else
-				   {
-				     DEBUG_Printf(DBG_CHN_MESG,"Unable to add breakpoint\n");
-				   }
-			       }
-    | tBREAK tNUM tEOL	       { struct name_hash *nh;
-				 DBG_VALUE value;
-				 DEBUG_GetCurrentAddress( &value.addr );
-				 DEBUG_FindNearestSymbol(&value.addr, TRUE,
-							 &nh, 0, NULL);
-				 if( nh != NULL )
-				   {
-				     DEBUG_GetLineNumberAddr(nh, $2, &value.addr, TRUE);
-				     value.type = NULL;
-				     value.cookie = DV_TARGET;
-				     DEBUG_AddBreakpoint( &value, NULL );
-				   }
-				 else
-				   {
-				     DEBUG_Printf(DBG_CHN_MESG,"Unable to add breakpoint\n");
-				   }
-                               }
-
-    | tBREAK tEOL              { DBG_VALUE value;
-				 DEBUG_GetCurrentAddress( &value.addr );
-				 value.type = NULL;
-				 value.cookie = DV_TARGET;
-                                 DEBUG_AddBreakpoint( &value, NULL );
-                               }
+      tBREAK '*' expr_addr tEOL{ DEBUG_AddBreakpoint( &$3, NULL ); DEBUG_FreeExprMem(); }
+    | tBREAK tIDENTIFIER tEOL  { DEBUG_AddBreakpointFromId($2, -1); }
+    | tBREAK tIDENTIFIER ':' tNUM tEOL  { DEBUG_AddBreakpointFromId($2, $4); }
+    | tBREAK tNUM tEOL	       { DEBUG_AddBreakpointFromLineno($2); }
+    | tBREAK tEOL              { DEBUG_AddBreakpointFromLineno(-1); }
 
 watch_command:
-      tWATCH '*' expr_addr tEOL { DEBUG_AddWatchpoint( &$3, 1 ); 
- 					     DEBUG_FreeExprMem(); }
-    | tWATCH tIDENTIFIER tEOL  { DBG_VALUE value;
-				 if( DEBUG_GetSymbolValue($2, -1, &value, TRUE) )
-				     DEBUG_AddWatchpoint( &value, 1 );
-				 else
-				     DEBUG_Printf(DBG_CHN_MESG,"Unable to add breakpoint\n");
-				}
+      tWATCH '*' expr_addr tEOL { DEBUG_AddWatchpoint( &$3, 1 ); DEBUG_FreeExprMem(); }
+    | tWATCH tIDENTIFIER tEOL   { DEBUG_AddWatchpointFromId($2, -1); }
 
 info_command:
       tINFO tBREAK tEOL         { DEBUG_InfoBreakpoints(); }
-    | tINFO tCLASS tSTRING tEOL	{ DEBUG_InfoClass( $3 ); DEBUG_FreeExprMem(); }
+    | tINFO tCLASS tSTRING tEOL	{ DEBUG_InfoClass( $3 ); }
     | tINFO tSHARE tEOL		{ DEBUG_InfoShare(); }
     | tINFO tMODULE expr_value tEOL   { DEBUG_DumpModule( $3 ); DEBUG_FreeExprMem(); }
     | tINFO tQUEUE expr_value tEOL    { DEBUG_DumpQueue( $3 ); DEBUG_FreeExprMem(); }
@@ -265,8 +215,7 @@
     | tINFO tSEGMENTS tEOL      { DEBUG_InfoSegments( 0, -1 ); }
     | tINFO tSTACK tEOL         { DEBUG_InfoStack(); }
     | tINFO tMAPS tEOL          { DEBUG_InfoVirtual(); }
-    | tINFO tWND expr_value tEOL      { DEBUG_InfoWindow( (HWND)$3 ); 
- 					     DEBUG_FreeExprMem(); }
+    | tINFO tWND expr_value tEOL{ DEBUG_InfoWindow( (HWND)$3 ); DEBUG_FreeExprMem(); }
     | tINFO tLOCAL tEOL         { DEBUG_InfoLocals(); }
     | tINFO tDISPLAY tEOL       { DEBUG_InfoDisplay(); }
 
@@ -278,8 +227,15 @@
     | tWALK tWND tNUM tEOL      { DEBUG_WalkWindows( $3, 0 ); }
     | tWALK tPROCESS tEOL       { DEBUG_WalkProcess(); }
     | tWALK tTHREAD tEOL        { DEBUG_WalkThreads(); }
-    | tWALK tMODREF expr_value tEOL   { DEBUG_WalkModref( $3 ); }
+    | tWALK tMODREF expr_value tEOL   { DEBUG_WalkModref( $3 ); DEBUG_FreeExprMem(); }
 
+run_command:
+      tRUN tEOL                 { DEBUG_Run(NULL); }
+    | tRUN tSTRING tEOL         { DEBUG_Run($2); }
+
+noprocess_state:
+      tNOPROCESS tEOL		{} /* <CR> shall not barf anything */
+    | tNOPROCESS tSTRING tEOL	{ DEBUG_Printf(DBG_CHN_MESG, "No process loaded, cannot execute '%s'\n", $2); }
 
 type_cast: 
       '(' type_expr ')'		{ $$ = $2; }
@@ -292,7 +248,7 @@
     | tUNSIGNED tINT		{ $$ = DEBUG_TypeCast(DT_BASIC, "unsigned int"); }
     | tLONG tUNSIGNED tINT	{ $$ = DEBUG_TypeCast(DT_BASIC, "long unsigned int"); }
     | tLONG tLONG tINT		{ $$ = DEBUG_TypeCast(DT_BASIC, "long long int"); }
-    | tLONG tLONG tUNSIGNED tINT { $$ = DEBUG_TypeCast(DT_BASIC, "long long unsigned int"); }
+    | tLONG tLONG tUNSIGNED tINT{ $$ = DEBUG_TypeCast(DT_BASIC, "long long unsigned int"); }
     | tSHORT tINT		{ $$ = DEBUG_TypeCast(DT_BASIC, "short int"); }
     | tSHORT tUNSIGNED tINT	{ $$ = DEBUG_TypeCast(DT_BASIC, "short unsigned int"); }
     | tSIGNED tCHAR		{ $$ = DEBUG_TypeCast(DT_BASIC, "signed char"); }
@@ -424,136 +380,41 @@
 }
 
 /***********************************************************************
- *           DEBUG_Main
+ *           DEBUG_Parser
  *
- * Debugger main loop.
+ * Debugger editline parser
  */
-BOOL DEBUG_Main( BOOL is_debug, BOOL force, DWORD code )
+BOOL	DEBUG_Parser(void)
 {
-    int newmode;
-    BOOL ret_ok;
-    char ch;
-
+    BOOL 	ret_ok;
+    BOOL	ret = TRUE;
 #ifdef YYDEBUG
     yydebug = 0;
 #endif
-
     yyin = stdin;
 
-    DEBUG_SuspendExecution();
-
-    if (!is_debug)
-    {
-#ifdef __i386__
-        if (DEBUG_IsSelectorSystem(DEBUG_context.SegCs))
-            DEBUG_Printf( DBG_CHN_MESG, " in 32-bit code (0x%08lx).\n", DEBUG_context.Eip );
-        else
-            DEBUG_Printf( DBG_CHN_MESG, " in 16-bit code (%04x:%04lx).\n",
-			  (WORD)DEBUG_context.SegCs, DEBUG_context.Eip );
-#else
-        DEBUG_Printf( DBG_CHN_MESG, " (0x%08lx).\n", GET_IP(&DEBUG_context) );
-#endif
-    }
-
-    DEBUG_LoadEntryPoints("Loading new modules symbols:\n");
-
-    if (force || !(is_debug && DEBUG_ShouldContinue( code, 
-						     DEBUG_CurrThread->dbg_exec_mode, 
-						     &DEBUG_CurrThread->dbg_exec_count )))
-    {
-        DBG_ADDR addr;
-        DEBUG_GetCurrentAddress( &addr );
-
-#ifdef __i386__
-        switch (newmode = DEBUG_GetSelectorType(addr.seg)) {
-	case 16: case 32: break;
-	default: DEBUG_Printf(DBG_CHN_MESG, "Bad CS (%ld)\n", addr.seg); newmode = 32;
-	}
-#else
-        newmode = 32;
-#endif
-        if (newmode != DEBUG_CurrThread->dbg_mode)
-            DEBUG_Printf(DBG_CHN_MESG,"In %d bit mode.\n", DEBUG_CurrThread->dbg_mode = newmode);
-
-	DEBUG_DoDisplay();
-
-        if (is_debug || force)
-	{
-	  /*
-	   * Do a quiet backtrace so that we have an idea of what the situation
-	   * is WRT the source files.
-	   */
-	    DEBUG_BackTrace(FALSE);
-	}
-	else
-        {
-	    /* This is a real crash, dump some info */
-            DEBUG_InfoRegisters();
-            DEBUG_InfoStack();
-#ifdef __i386__
-            if (DEBUG_CurrThread->dbg_mode == 16)
-            {
-	        DEBUG_InfoSegments( DEBUG_context.SegDs >> 3, 1 );
-                if (DEBUG_context.SegEs != DEBUG_context.SegDs)
-                    DEBUG_InfoSegments( DEBUG_context.SegEs >> 3, 1 );
-            }
-            DEBUG_InfoSegments( DEBUG_context.SegFs >> 3, 1 );
-#endif
-            DEBUG_BackTrace(TRUE);
-        }
-
-	if (!is_debug ||
-            (DEBUG_CurrThread->dbg_exec_mode == EXEC_STEPI_OVER) ||
-            (DEBUG_CurrThread->dbg_exec_mode == EXEC_STEPI_INSTR))
-        {
-	    /* Show where we crashed */
-	    curr_frame = 0;
-	    DEBUG_PrintAddress( &addr, DEBUG_CurrThread->dbg_mode, TRUE );
-	    DEBUG_Printf(DBG_CHN_MESG,":  ");
-	    DEBUG_Disasm( &addr, TRUE );
-	    DEBUG_Printf( DBG_CHN_MESG, "\n" );
-        }
-
-        ret_ok = 0;
-        do
-        {
-	    __TRY 
-	    {
-	       issue_prompt();
-	       if (yyparse()) {
-		  DEBUG_CurrThread->dbg_exec_mode = EXEC_KILL;
-		  ret_ok = TRUE;
-	       } else {
-		  flush_symbols();
-
-		  DEBUG_GetCurrentAddress( &addr );
-		  ret_ok = DEBUG_ValidateRegisters() && 
-		     DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear(&addr), &ch, 1);
-	       }
-	    } 
-	    __EXCEPT(wine_dbg_cmd)
-	    {
-	       ret_ok = FALSE;
-	    }
-	    __ENDTRY;
-
-        } while (!ret_ok);
-    }
-
-    DEBUG_CurrThread->dbg_exec_mode = DEBUG_RestartExecution( DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count );
-    /*
-     * This will have gotten absorbed into the breakpoint info
-     * if it was used.  Otherwise it would have been ignored.
-     * In any case, we don't mess with it any more.
-     */
-    if (DEBUG_CurrThread->dbg_exec_mode == EXEC_CONT || DEBUG_CurrThread->dbg_exec_mode == EXEC_PASS)
-	DEBUG_CurrThread->dbg_exec_count = 0;
-    
-    return (DEBUG_CurrThread->dbg_exec_mode == EXEC_PASS) ? DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
+    ret_ok = FALSE;
+    do {
+       __TRY {
+	  issue_prompt();
+	  if ((ret = yyparse())) {
+	     DEBUG_FlushSymbols();
+	     
+	     ret_ok = (DEBUG_CurrThread) ? DEBUG_ValidateRegisters() : TRUE;
+	  } else {
+	     ret_ok = TRUE;
+	  }
+       } __EXCEPT(wine_dbg_cmd) {
+	  ret_ok = FALSE;
+       }
+       __ENDTRY;
+       
+    } while (!ret_ok);
+    return ret;
 }
 
 int yyerror(char* s)
 {
-   DEBUG_Printf(DBG_CHN_MESG,"%s\n", s);
+   DEBUG_Printf(DBG_CHN_MESG, "%s\n", s);
    return 0;
 }
diff --git a/debugger/debug.l b/debugger/debug.l
index 0adf93c..cb8dc64 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -2,6 +2,7 @@
  * Lexical scanner for command line parsing
  *
  * Copyright 1993 Eric Youngdale
+ *           2000 Eric Pouech
  */
 
 %{
@@ -10,12 +11,6 @@
 #include "debugger.h"
 #include "y.tab.h"
 
-#ifdef DBG_need_heap
-#define malloc(x) DBG_alloc(x)
-#define realloc(x,y) DBG_realloc(x,y)
-#define free(x) DBG_free(x)
-#endif
-
 #ifndef DONT_USE_READLINE
 #undef YY_INPUT
 #define YY_INPUT(buf,result,max_size) \
@@ -23,7 +18,7 @@
 	    YY_FATAL_ERROR( "read() in flex scanner failed" );
 
 static int dbg_read(char * buf, int size);
-static char * make_symbol(char *);
+static char * DEBUG_MakeSymbol(char *);
 
 #endif  /* DONT_USE_READLINE */
 
@@ -47,40 +42,42 @@
 %s WALK_CMD
 %s SHOW_CMD
 %s NOCMD
-%s DEBUGSTR
 
+%x ASTRING_EXPECTED
+%x NOPROCESS
 %%
+                                        /* set to special state when no process is loaded. */
+                                        if (!DEBUG_CurrProcess && YYSTATE == INITIAL) {BEGIN(NOPROCESS);}
 
-\n		{ BEGIN(0); syntax_error = 0; 
-		  return tEOL; } /*Indicates end of command.  Reset state. */
+<*>\n		                        { BEGIN(INITIAL); syntax_error = 0; return tEOL; } 
+                                        /* Indicates end of command. Reset state. */
 
-"||"		{ return OP_LOR; }
-"&&"		{ return OP_LAND; }
-"=="		{ return OP_EQ; }
-"!="		{ return OP_NE; }
-"<="		{ return OP_LE; }
-">="		{ return OP_GE; }
-"<<"		{ return OP_SHL; }
-">>"		{ return OP_SHR; }
-"->"		{ return OP_DRF; }
-[-+<=>|&^()*/%:!~,\.]	{ return *yytext; }
-"["		{ return *yytext; }
-"]"		{ return *yytext; }
+"||"					{ return OP_LOR; }
+"&&"					{ return OP_LAND; }
+"=="					{ return OP_EQ; }
+"!="					{ return OP_NE; }
+"<="					{ return OP_LE; }
+">="					{ return OP_GE; }
+"<<"					{ return OP_SHL; }
+">>"					{ return OP_SHR; }
+"->"					{ return OP_DRF; }
+[-+<=>|&^()*/%:!~,\.]			{ return *yytext; }
+"["					{ return *yytext; }
+"]"					{ return *yytext; }
 
-"0x"{HEXDIGIT}+      { sscanf(yytext, "%x", &yylval.integer); return tNUM; }
-{DIGIT}+             { sscanf(yytext, "%d", &yylval.integer); return tNUM; }
+"0x"{HEXDIGIT}+      			{ sscanf(yytext, "%x", &yylval.integer); return tNUM; }
+{DIGIT}+             			{ sscanf(yytext, "%d", &yylval.integer); return tNUM; }
 
+<FORMAT_EXPECTED>"/"{DIGIT}+{FORMAT}	{ char* last;
+                                          yylval.integer = strtol( yytext+1, &last, NULL ) << 8;
+                                          yylval.integer |= *last;
+                                          return tFORMAT; }
 
-<FORMAT_EXPECTED>"/"{DIGIT}+{FORMAT}  { char * last;
-                       yylval.integer = strtol( yytext+1, &last, NULL );
-                       yylval.integer = (yylval.integer << 8) | *last;
-                       return tFORMAT; }
+<FORMAT_EXPECTED>"/"{FORMAT}          	{ yylval.integer = (1 << 8) | yytext[1]; return tFORMAT; }
 
-
-<FORMAT_EXPECTED>"/"{FORMAT}          { yylval.integer = (1 << 8) | yytext[1]; return tFORMAT; }
-
-{STRING} { yylval.string = make_symbol(yytext); return tSTRING; }
-<DEBUGSTR>[a-z+\-,]* { yylval.string = yytext; return tDEBUGSTR; }
+{STRING} 				{ yylval.string = DEBUG_MakeSymbol(yytext); return tSTRING; }
+<ASTRING_EXPECTED>[^\n]+                { char* p = yytext; while (*p == ' ' || *p == '\t') p++;
+                                          yylval.string = DEBUG_MakeSymbol(p); return tSTRING; }
 
 <INITIAL>info|inf|in			{ BEGIN(INFO_CMD); return tINFO; }
 <INITIAL>up				{ BEGIN(NOCMD); return tUP; }
@@ -93,9 +90,9 @@
 <INITIAL,INFO_CMD,DEL_CMD>display|displa|displ|disp	{ BEGIN(FORMAT_EXPECTED); return tDISPLAY; }
 <INITIAL>undisplay|undispla|undispl|undisp|undis|undi|und	{ BEGIN(NOCMD); return tUNDISPLAY; }
 <INITIAL>delete|delet|dele|del		{ BEGIN(DEL_CMD); return tDELETE; }
-<INITIAL>quit|qui|qu|q			{ BEGIN(NOCMD); return tQUIT; }
+<INITIAL,NOPROCESS>quit|qui|qu|q	{ BEGIN(NOCMD); return tQUIT; }
 <INITIAL>set|se				{ BEGIN(NOCMD); return tSET; }
-<INITIAL>walk|w				{ BEGIN(WALK_CMD); return tWALK; }
+<INITIAL,NOPROCESS>walk|w		{ BEGIN(WALK_CMD); return tWALK; }
 <INITIAL>x				{ BEGIN(FORMAT_EXPECTED); return tEXAM; }
 <INITIAL>help|hel|he|"?"		{ BEGIN(HELP_CMD); return tHELP; }
 
@@ -121,11 +118,12 @@
 <INITIAL,INFO_CMD,DEL_CMD>break|brea|bre|br|b	{ BEGIN(PATH_EXPECTED); return tBREAK; }
 <INITIAL>watch|watc|wat			{ BEGIN(PATH_EXPECTED); return tWATCH; }
 <INITIAL>whatis|whati|what		{ BEGIN(PATH_EXPECTED); return tWHATIS; }
-
+<INITIAL,NOPROCESS>run|ru|r     	{ BEGIN(ASTRING_EXPECTED); return tRUN;}
+<NOPROCESS>attach|attac|atta|att 	{ BEGIN(NOCMD); return tATTACH; }
 <INFO_CMD>share|shar|sha		{ return tSHARE; }
 <INFO_CMD>locals|local|loca|loc		{ return tLOCAL; }
 <INFO_CMD,WALK_CMD>class|clas|cla       { return tCLASS; }
-<INFO_CMD,WALK_CMD>module|modul|modu|mod  { return tMODULE; }
+<INFO_CMD,WALK_CMD>module|modul|modu|mod { return tMODULE; }
 <INFO_CMD,WALK_CMD>queue|queu|que	{ return tQUEUE; }
 <INFO_CMD,WALK_CMD>process|proces|proce|proc   		{ return tPROCESS; }
 <INFO_CMD,WALK_CMD>threads|thread|threa|thre|thr|th { return tTHREAD; }
@@ -138,7 +136,7 @@
 <HELP_CMD>info|inf|in                   { return tINFO; }
 
 <INITIAL,SHOW_CMD>directories|directorie|directori|director|directo|direct|direc|direc|dir { 
-			BEGIN(PATH_EXPECTED); return tDIR; }
+			                  BEGIN(PATH_EXPECTED); return tDIR; }
 
 char					{ return tCHAR; }
 short					{ return tSHORT; }
@@ -152,20 +150,18 @@
 union					{ return tUNION; }
 enum					{ return tENUM; }
 
-{IDENTIFIER}	{ yylval.string = make_symbol(yytext); return tIDENTIFIER; }
-"$"{IDENTIFIER}	{ yylval.string = make_symbol(yytext+1); return tINTVAR; }
+{IDENTIFIER}				{ yylval.string = DEBUG_MakeSymbol(yytext); return tIDENTIFIER; }
+"$"{IDENTIFIER}				{ yylval.string = DEBUG_MakeSymbol(yytext+1); return tINTVAR; }
 
-<PATH_EXPECTED>{PATHNAME}	{ yylval.string = make_symbol(yytext); return tPATH; }
+<PATH_EXPECTED>{PATHNAME}		{ yylval.string = DEBUG_MakeSymbol(yytext); return tPATH; }
 
-[ \t]+        /* Eat up whitespace */
+<*>[ \t]+                               /* Eat up whitespace */	
 
-.		{ if (syntax_error == 0)
-                  {
-		    syntax_error ++; DEBUG_Printf(DBG_CHN_MESG, "Syntax Error\n");
-                  }
-		}
-
-
+<NOPROCESS>.                            { BEGIN(ASTRING_EXPECTED); yyless(0); return tNOPROCESS;}
+<*>.                                    { if (syntax_error == 0) {
+                                             syntax_error++; 
+					     DEBUG_Printf(DBG_CHN_MESG, "Syntax Error (%s)\n", yytext); }
+		                        }
 %%
 
 #ifndef yywrap
@@ -206,7 +202,7 @@
     
     for (;;)
     {
-        flush_symbols();
+        DEBUG_FlushSymbols();
         line = readline ("Wine-dbg>");
         if (!line)
         {
@@ -226,7 +222,7 @@
             add_history( line );
             strncpy( last_line, line, 255 );
             last_line[255] = '\0'; 
-       }
+        }
 
         free( line );
         line = last_line;
@@ -249,14 +245,15 @@
 static char *local_symbols[30];
 static int next_symbol;
 
-static char * make_symbol(char * symbol)
+static char * DEBUG_MakeSymbol(char * symbol)
 {
-        return local_symbols[next_symbol++] = DBG_strdup(symbol);
+        assert(0 <= next_symbol && next_symbol < (sizeof(local_symbols) / sizeof(local_symbols[0])));
+	return local_symbols[next_symbol++] = DBG_strdup(symbol);
 }
 
-void flush_symbols(void)
+void DEBUG_FlushSymbols(void)
 {
-	while(--next_symbol>= 0) DBG_free(local_symbols[next_symbol]);
+	while(--next_symbol >= 0) DBG_free(local_symbols[next_symbol]);
 	next_symbol = 0;
 }
 
diff --git a/debugger/debugger.h b/debugger/debugger.h
index 3514380..4ee5935 100644
--- a/debugger/debugger.h
+++ b/debugger/debugger.h
@@ -112,7 +112,6 @@
 				 * and set breakpoint there - not at the
 				 * instr just after the call.
 				 */
-    EXEC_KILL			/* terminate debugging session */
 };
 
 #define	DBG_BREAK 	0
@@ -224,24 +223,16 @@
 
 #define	OFFSET_OF(__c,__f)		((int)(((char*)&(((__c*)0)->__f))-((char*)0)))
 
-
-
-#ifdef __i386__
-# define GET_IP(context) ((DWORD)(context)->Eip)
-#endif
-#ifdef __sparc__
-# define GET_IP(context) ((DWORD)(context)->pc)
-#endif
-
-#if !defined(GET_IP)
-# error You must define GET_IP for this CPU
-#endif
-
+  /* from winelib.so */
+extern void DEBUG_ExternalDebugger(void);
 
   /* debugger/break.c */
 extern void DEBUG_SetBreakpoints( BOOL set );
 extern void DEBUG_AddBreakpoint( const DBG_VALUE *addr, BOOL (*func)(void) );
+extern void DEBUG_AddBreakpointFromId( const char *name, int lineno );
+extern void DEBUG_AddBreakpointFromLineno( int lineno );
 extern void DEBUG_AddWatchpoint( const DBG_VALUE *addr, int is_write );
+extern void DEBUG_AddWatchpointFromId( const char *name, int lineno );
 extern void DEBUG_DelBreakpoint( int num );
 extern void DEBUG_EnableBreakpoint( int num, BOOL enable );
 extern void DEBUG_InfoBreakpoints(void);
@@ -250,17 +241,17 @@
 extern void DEBUG_SuspendExecution( void );
 extern enum exec_mode DEBUG_RestartExecution( enum exec_mode mode, int count );
 extern BOOL DEBUG_IsFctReturn(void);
-extern int DEBUG_AddBPCondition(int bpnum, struct expr * exp);
+extern int  DEBUG_AddBPCondition(int bpnum, struct expr * exp);
 
   /* debugger/db_disasm.c */
 extern void DEBUG_Disasm( DBG_ADDR *addr, int display );
 
   /* debugger/dbg.y */
-extern BOOL DEBUG_Main( BOOL is_debug, BOOL force, DWORD code );
+extern BOOL DEBUG_Parser(void);
 extern void DEBUG_Exit( DWORD );
 
   /* debugger/debug.l */
-extern void flush_symbols(void);
+extern void DEBUG_FlushSymbols(void);
 
   /* debugger/display.c */
 extern int DEBUG_DoDisplay(void);
@@ -294,9 +285,6 @@
 extern int DEBUG_FreeExpr(struct expr * exp);
 extern int DEBUG_DisplayExpr(const struct expr * exp);
 
-  /* debugger/external.c */
-extern void DEBUG_ExternalDebugger(void);
-
   /* debugger/hash.c */
 extern struct name_hash * DEBUG_AddSymbol( const char *name, 
 					   const DBG_VALUE *addr,
@@ -378,6 +366,7 @@
 				   void* mod_addr, HMODULE hmod);
 extern DBG_MODULE* DEBUG_FindModuleByName(const char* name, int type);
 extern DBG_MODULE* DEBUG_FindModuleByHandle(HANDLE handle, int type);
+extern DBG_MODULE* DEBUG_GetProcessMainModule(DBG_PROCESS* process);
 extern DBG_MODULE* DEBUG_RegisterPEModule(HMODULE, u_long load_addr, const char* name);
 extern DBG_MODULE* DEBUG_RegisterELFModule(u_long load_addr, const char* name);
 extern void DEBUG_InfoShare(void);
@@ -456,8 +445,11 @@
 extern int	DEBUG_Printf(int chn, const char* format, ...);
 #endif
 extern DBG_INTVAR*	DEBUG_GetIntVar(const char*);
+extern BOOL DEBUG_Attach(DWORD pid, BOOL cofe);
+extern void DEBUG_Run(const char* args);
+extern int curr_frame;
 
-  /* Choose your allocator! */
+/* Choose your allocator! */
 #if 1
 /* this one is libc's fast one */
 extern void*	DEBUG_XMalloc(size_t size);
diff --git a/debugger/intvar.h b/debugger/intvar.h
index 27675b0..ac30a56 100644
--- a/debugger/intvar.h
+++ b/debugger/intvar.h
@@ -9,6 +9,7 @@
 INTERNAL_VAR(BreakAllThreadsStartup,	FALSE,		NULL,  			DEBUG_TypeIntConst)
 INTERNAL_VAR(BreakOnCritSectTimeOut,    FALSE,          NULL,  			DEBUG_TypeIntConst)
 INTERNAL_VAR(BreakOnAttach,		FALSE,		NULL,			DEBUG_TypeIntConst)
+INTERNAL_VAR(BreakOnFirstChance,	TRUE,		NULL,			DEBUG_TypeIntConst)
 
    /* output handling */
 INTERNAL_VAR(ConChannelMask,		DBG_CHN_MESG,	NULL,  			DEBUG_TypeIntConst)
diff --git a/debugger/memory.c b/debugger/memory.c
index d1feb93..455e94e 100644
--- a/debugger/memory.c
+++ b/debugger/memory.c
@@ -117,9 +117,11 @@
     if (!DEBUG_FixSegment( addr ) && DEBUG_IsSelectorSystem(addr->seg)) 
        addr->seg = 0;
     addr->off  = DEBUG_context.Eip;
+#elif defined(__sparc__)
+	 addr->seg = 0;
+    addr->off = DEBUG_context.pc;
 #else
-    addr->seg  = 0;
-    addr->off  = GET_IP( &DEBUG_context );
+#	error You must define GET_IP for this CPU
 #endif
 }
 
diff --git a/debugger/module.c b/debugger/module.c
index 5ab651a..011cc75 100644
--- a/debugger/module.c
+++ b/debugger/module.c
@@ -92,6 +92,21 @@
 }
 
 /***********************************************************************
+ *		DEBUG_GetProcessMainModule
+ */
+DBG_MODULE*	DEBUG_GetProcessMainModule(DBG_PROCESS* process)
+{
+    DBG_MODULE*	wmod;
+
+    if (!process) return NULL;
+
+    /* main module is the first to be loaded on a given process, so it's the last on
+     * the list */
+    for (wmod = process->modules; wmod && wmod->next; wmod = wmod->next);
+    return wmod;
+}
+
+/***********************************************************************
  *			DEBUG_RegisterELFModule
  *
  * ELF modules are also entered into the list - this is so that we
@@ -139,6 +154,7 @@
     return wmod;
 }
 
+#if 0
 /***********************************************************************
  *           DEBUG_GetEP16
  *
@@ -230,6 +246,7 @@
     }
     GlobalUnlock16(module->nrname_handle);
 }
+#endif
 
 /***********************************************************************
  *			DEBUG_LoadModule32
@@ -355,10 +372,14 @@
  */
 int DEBUG_LoadEntryPoints(const char* pfx)
 {
+    int		first = 0;
+    /* FIXME: with address space separation in space, this is plain wrong
+     *	      it requires the 16 bit WOW debugging interface...
+     */
+#if 0
     MODULEENTRY	entry;
     NE_MODULE	module;
     void*	moduleAddr;
-    int		first = 0;
     int		rowcount = 0;
     int		len;
 
@@ -390,6 +411,7 @@
 	
 	DEBUG_LoadModule16(entry.hModule, &module, moduleAddr, entry.szModule);
     } while (ModuleNext16(&entry));
+#endif
     
     if (first) DEBUG_Printf(DBG_CHN_MESG, "\n"); 
     return first;
diff --git a/debugger/registers.c b/debugger/registers.c
index 4dde821..4ff5952 100644
--- a/debugger/registers.c
+++ b/debugger/registers.c
@@ -121,6 +121,9 @@
  */
 BOOL DEBUG_ValidateRegisters(void)
 {
+   DBG_ADDR	addr;
+   char		ch;
+
 #ifdef __i386__
     if (DEBUG_context.EFlags & V86_FLAG) return TRUE;
 
@@ -157,9 +160,13 @@
 		      (WORD)DEBUG_context.SegSs );
         return FALSE;
     }
-    return TRUE;
+
 #undef CHECK_SEG
 #else
-    return TRUE;
+    /* to be written */
 #endif
+
+    /* check if PC is correct */
+    DEBUG_GetCurrentAddress(&addr);
+    return DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear(&addr), &ch, 1);
 }
diff --git a/debugger/stack.c b/debugger/stack.c
index 36ed896..8e4c99f 100644
--- a/debugger/stack.c
+++ b/debugger/stack.c
@@ -30,7 +30,6 @@
 
 static int nframe;
 static struct bt_info * frames = NULL;
-int curr_frame;
 
 typedef struct
 {
diff --git a/debugger/types.c b/debugger/types.c
index cab945b..65cee4a 100644
--- a/debugger/types.c
+++ b/debugger/types.c
@@ -897,7 +897,11 @@
 	    }
 	}
       break;
+    case DT_FUNC:
+      DEBUG_Printf(DBG_CHN_MESG, "Function at ???\n");
+      break; 
     default:
+      DEBUG_Printf(DBG_CHN_MESG, "Unknown type (%d)\n", value->type->type);
       assert(FALSE);
       break;
     }
diff --git a/debugger/winedbg.c b/debugger/winedbg.c
index e459456..bf4d344 100644
--- a/debugger/winedbg.c
+++ b/debugger/winedbg.c
@@ -28,6 +28,8 @@
 DWORD		DEBUG_CurrTid;
 DWORD		DEBUG_CurrPid;
 CONTEXT		DEBUG_context;
+int 		curr_frame = 0;
+static char*	DEBUG_LastCmdLine = NULL;
 
 static DBG_PROCESS* proc = NULL;
 DBG_INTVAR DEBUG_IntVars[DBG_IV_LAST];
@@ -164,6 +166,7 @@
     if (p->prev) p->prev->next = p->next;
     if (p->next) p->next->prev = p->prev;
     if (p == proc) proc = p->next;
+    if (p == DEBUG_CurrProcess) DEBUG_CurrProcess = NULL;
     DBG_free(p);
 }
 
@@ -253,17 +256,120 @@
     if (t->next) t->next->prev = t->prev;
     if (t == t->process->threads) t->process->threads = t->next;
     t->process->num_threads--;
+    if (t == DEBUG_CurrThread) DEBUG_CurrThread = NULL;
     DBG_free(t);
 }
 
-static	BOOL	DEBUG_HandleException( EXCEPTION_RECORD *rec, BOOL first_chance, BOOL force )
+BOOL				DEBUG_Attach(DWORD pid, BOOL cofe)
+{
+    if (!(DEBUG_CurrProcess = DEBUG_AddProcess(pid, 0))) return FALSE;
+
+    if (!DebugActiveProcess(pid)) {
+	DEBUG_Printf(DBG_CHN_ERR, "Can't attach process %ld: %ld\n", 
+		     pid, GetLastError());
+	return FALSE;
+    }
+    DEBUG_CurrProcess->continue_on_first_exception = cofe;
+    return TRUE;
+}
+
+static  BOOL	DEBUG_ExceptionProlog(BOOL is_debug, BOOL force, DWORD code)
+{
+    DBG_ADDR	addr;
+    int		newmode;
+
+    DEBUG_GetCurrentAddress(&addr);
+    DEBUG_SuspendExecution();
+
+    if (!is_debug) {
+#ifdef __i386__
+        if (DEBUG_IsSelectorSystem(DEBUG_context.SegCs))
+            DEBUG_Printf(DBG_CHN_MESG, " in 32-bit code (0x%08lx).\n", addr.off);
+        else
+            DEBUG_Printf(DBG_CHN_MESG, " in 16-bit code (%04x:%04lx).\n",
+			 LOWORD(addr.seg), addr.off);
+#else
+        DEBUG_Printf(DBG_CHN_MESG, " (0x%08lx).\n", addr.off);
+#endif
+    }
+
+    DEBUG_LoadEntryPoints("Loading new modules symbols:\n");
+
+    if (!force && is_debug && 
+	DEBUG_ShouldContinue(code, 
+			     DEBUG_CurrThread->dbg_exec_mode, 
+			     &DEBUG_CurrThread->dbg_exec_count))
+	return FALSE;
+
+#ifdef __i386__
+    switch (newmode = DEBUG_GetSelectorType(addr.seg)) {
+    case 16: case 32: break;
+    default: DEBUG_Printf(DBG_CHN_MESG, "Bad CS (%ld)\n", addr.seg); newmode = 32;
+    }
+#else
+    newmode = 32;
+#endif
+    if (newmode != DEBUG_CurrThread->dbg_mode)
+	DEBUG_Printf(DBG_CHN_MESG,"In %d bit mode.\n", DEBUG_CurrThread->dbg_mode = newmode);
+
+    DEBUG_DoDisplay();
+
+    if (is_debug || force) {
+	/*
+	 * Do a quiet backtrace so that we have an idea of what the situation
+	 * is WRT the source files.
+	 */
+	DEBUG_BackTrace(FALSE);
+    } else {
+	/* This is a real crash, dump some info */
+	DEBUG_InfoRegisters();
+	DEBUG_InfoStack();
+#ifdef __i386__
+	if (DEBUG_CurrThread->dbg_mode == 16) {
+	    DEBUG_InfoSegments(DEBUG_context.SegDs >> 3, 1);
+	    if (DEBUG_context.SegEs != DEBUG_context.SegDs)
+		DEBUG_InfoSegments(DEBUG_context.SegEs >> 3, 1);
+	}
+	DEBUG_InfoSegments(DEBUG_context.SegFs >> 3, 1);
+#endif
+	DEBUG_BackTrace(TRUE);
+    }
+
+    if (!is_debug ||
+	(DEBUG_CurrThread->dbg_exec_mode == EXEC_STEPI_OVER) ||
+	(DEBUG_CurrThread->dbg_exec_mode == EXEC_STEPI_INSTR)) {
+	/* Show where we crashed */
+	curr_frame = 0;
+	DEBUG_PrintAddress( &addr, DEBUG_CurrThread->dbg_mode, TRUE );
+	DEBUG_Printf(DBG_CHN_MESG,":  ");
+	DEBUG_Disasm( &addr, TRUE );
+	DEBUG_Printf( DBG_CHN_MESG, "\n" );
+    }
+    return TRUE;
+}
+
+static  DWORD	DEBUG_ExceptionEpilog(void)
+{
+    DEBUG_CurrThread->dbg_exec_mode = DEBUG_RestartExecution(DEBUG_CurrThread->dbg_exec_mode, 
+							     DEBUG_CurrThread->dbg_exec_count);
+    /*
+     * This will have gotten absorbed into the breakpoint info
+     * if it was used.  Otherwise it would have been ignored.
+     * In any case, we don't mess with it any more.
+     */
+    if (DEBUG_CurrThread->dbg_exec_mode == EXEC_CONT || DEBUG_CurrThread->dbg_exec_mode == EXEC_PASS)
+	DEBUG_CurrThread->dbg_exec_count = 0;
+    
+    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)
 {
     BOOL	is_debug = FALSE;
-    BOOL	ret;
+    BOOL	ret = TRUE;
 
-    /* FIXME: need for a configuration var ? */
-    /* pass to app first ??? */
-    /* if (first_chance && !force) return 0; */
+    *cont = DBG_CONTINUE;
+    if (first_chance && !force && !DBG_IVAR(BreakOnFirstChance)) return TRUE;
 
     switch (rec->ExceptionCode)
     {
@@ -276,50 +382,50 @@
     if (!is_debug)
     {
         /* print some infos */
-        DEBUG_Printf( DBG_CHN_MESG, "%s: ",
-		      first_chance ? "First chance exception" : "Unhandled exception" );
+        DEBUG_Printf(DBG_CHN_MESG, "%s: ",
+		      first_chance ? "First chance exception" : "Unhandled exception");
         switch (rec->ExceptionCode)
         {
         case EXCEPTION_INT_DIVIDE_BY_ZERO:
-            DEBUG_Printf( DBG_CHN_MESG, "divide by zero" );
+            DEBUG_Printf(DBG_CHN_MESG, "divide by zero");
             break;
         case EXCEPTION_INT_OVERFLOW:
-            DEBUG_Printf( DBG_CHN_MESG, "overflow" );
+            DEBUG_Printf(DBG_CHN_MESG, "overflow");
             break;
         case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
-            DEBUG_Printf( DBG_CHN_MESG, "array bounds " );
+            DEBUG_Printf(DBG_CHN_MESG, "array bounds ");
             break;
         case EXCEPTION_ILLEGAL_INSTRUCTION:
-            DEBUG_Printf( DBG_CHN_MESG, "illegal instruction" );
+            DEBUG_Printf(DBG_CHN_MESG, "illegal instruction");
             break;
         case EXCEPTION_STACK_OVERFLOW:
-            DEBUG_Printf( DBG_CHN_MESG, "stack overflow" );
+            DEBUG_Printf(DBG_CHN_MESG, "stack overflow");
             break;
         case EXCEPTION_PRIV_INSTRUCTION:
-            DEBUG_Printf( DBG_CHN_MESG, "priviledged instruction" );
+            DEBUG_Printf(DBG_CHN_MESG, "priviledged instruction");
             break;
         case EXCEPTION_ACCESS_VIOLATION:
             if (rec->NumberParameters == 2)
-                DEBUG_Printf( DBG_CHN_MESG, "page fault on %s access to 0x%08lx", 
+                DEBUG_Printf(DBG_CHN_MESG, "page fault on %s access to 0x%08lx", 
 			      rec->ExceptionInformation[0] ? "write" : "read",
-			      rec->ExceptionInformation[1] );
+			      rec->ExceptionInformation[1]);
             else
-                DEBUG_Printf( DBG_CHN_MESG, "page fault" );
+                DEBUG_Printf(DBG_CHN_MESG, "page fault");
             break;
         case EXCEPTION_DATATYPE_MISALIGNMENT:
-            DEBUG_Printf( DBG_CHN_MESG, "Alignment" );
+            DEBUG_Printf(DBG_CHN_MESG, "Alignment");
             break;
         case CONTROL_C_EXIT:
-            DEBUG_Printf( DBG_CHN_MESG, "^C" );
+            DEBUG_Printf(DBG_CHN_MESG, "^C");
             break;
         case EXCEPTION_CRITICAL_SECTION_WAIT:
-            DEBUG_Printf( DBG_CHN_MESG, "critical section %08lx wait failed", 
-			  rec->ExceptionInformation[0] );
+            DEBUG_Printf(DBG_CHN_MESG, "critical section %08lx wait failed", 
+			  rec->ExceptionInformation[0]);
 	    if (!DBG_IVAR(BreakOnCritSectTimeOut))
-		return DBG_CONTINUE;
+		return TRUE;
             break;
         default:
-            DEBUG_Printf( DBG_CHN_MESG, "%08lx", rec->ExceptionCode );
+            DEBUG_Printf(DBG_CHN_MESG, "%08lx", rec->ExceptionCode);
             break;
         }
 	DEBUG_Printf(DBG_CHN_MESG, "\n");
@@ -334,7 +440,15 @@
 #endif
 		 DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count);
 
-    ret = DEBUG_Main( is_debug, force, rec->ExceptionCode );
+    if (DEBUG_ExceptionProlog(is_debug, force, rec->ExceptionCode)) {
+	for (;;) {
+	    ret = DEBUG_Parser();
+	    if (!ret || DEBUG_CurrThread->dbg_exec_mode != EXEC_PASS || first_chance)
+		break;
+	    DEBUG_Printf(DBG_CHN_MESG, "Cannot pass on last chance exception. You must use cont\n");
+	}
+    }
+    *cont = DEBUG_ExceptionEpilog();
 
     DEBUG_Printf(DBG_CHN_TRACE, 
 		 "Exiting debugger 	PC=%lx EFL=%08lx mode=%d count=%d\n",
@@ -352,7 +466,7 @@
 {
     char		buffer[256];
     BOOL		ret;
-    
+
     DEBUG_CurrPid = de->dwProcessId;
     DEBUG_CurrTid = de->dwThreadId;
 
@@ -400,12 +514,11 @@
 		break;
 	    }
 	    
-	    *cont = DEBUG_HandleException(&de->u.Exception.ExceptionRecord, 
-					  de->u.Exception.dwFirstChance, 
-					  DEBUG_CurrThread->wait_for_first_exception);
-	    if (DEBUG_CurrThread->dbg_exec_mode == EXEC_KILL) {
-		ret = FALSE;
-	    } else {
+	    ret = DEBUG_HandleException(&de->u.Exception.ExceptionRecord, 
+					de->u.Exception.dwFirstChance, 
+					DEBUG_CurrThread->wait_for_first_exception,
+					cont);
+	    if (DEBUG_CurrThread) {
 		DEBUG_CurrThread->wait_for_first_exception = 0;
 		SetThreadContext(DEBUG_CurrThread->handle, &DEBUG_context);
 	    }
@@ -533,7 +646,8 @@
 	    /* kill last thread */
 	    DEBUG_DelThread(DEBUG_CurrProcess->threads);
 	    DEBUG_DelProcess(DEBUG_CurrProcess);
-	    ret = FALSE;
+
+	    DEBUG_Printf(DBG_CHN_MESG, "Process of pid=%08lx has terminated\n", DEBUG_CurrPid);
 	    break;
 	    
 	case LOAD_DLL_DEBUG_EVENT:
@@ -591,31 +705,73 @@
 	ret = TRUE;
     }
     __ENDTRY;
-
     return ret;
 }
 
-static	DWORD	DEBUG_MainLoop(DWORD pid)
+static	DWORD	DEBUG_MainLoop(void)
 {
     DEBUG_EVENT		de;
     DWORD		cont;
-    BOOL		ret = TRUE;
+    BOOL		ret;
 
-    DEBUG_Printf(DBG_CHN_MESG, " on pid %ld\n", pid);
+    DEBUG_Printf(DBG_CHN_MESG, " on pid %ld\n", DEBUG_CurrPid);
     
-    while (ret && WaitForDebugEvent(&de, INFINITE)) {
-	ret = DEBUG_HandleDebugEvent(&de, &cont);
-	ContinueDebugEvent(de.dwProcessId, de.dwThreadId, cont);
-    }
+    for (ret = TRUE; ret; ) {
+	/* wait until we get at least one loaded process */
+	while (!proc && (ret = DEBUG_Parser()));
+	if (!ret) break;
+
+	while (ret && WaitForDebugEvent(&de, INFINITE)) {
+	    ret = DEBUG_HandleDebugEvent(&de, &cont);
+	    ContinueDebugEvent(de.dwProcessId, de.dwThreadId, cont);
+	}
+    };
     
-    DEBUG_Printf(DBG_CHN_MESG, "WineDbg terminated on pid %ld\n", pid);
+    DEBUG_Printf(DBG_CHN_MESG, "WineDbg terminated on pid %ld\n", DEBUG_CurrPid);
 
     return 0;
 }
 
+static	BOOL	DEBUG_Start(LPSTR cmdLine)
+{
+    PROCESS_INFORMATION	info;
+    STARTUPINFOA	startup;
+
+    memset(&startup, 0, sizeof(startup));
+    startup.cb = sizeof(startup);
+    startup.dwFlags = STARTF_USESHOWWINDOW;
+    startup.wShowWindow = SW_SHOWNORMAL;
+    
+    if (!CreateProcess(NULL, cmdLine, NULL, NULL, 
+		       FALSE, DEBUG_PROCESS, NULL, NULL, &startup, &info)) {
+	DEBUG_Printf(DBG_CHN_MESG, "Couldn't start process '%s'\n", cmdLine);
+	return FALSE;
+    }
+    DEBUG_CurrPid = info.dwProcessId;
+    if (!(DEBUG_CurrProcess = DEBUG_AddProcess(DEBUG_CurrPid, 0))) return FALSE;
+
+    return TRUE;
+}
+
+void	DEBUG_Run(const char* args)
+{
+    DBG_MODULE*	wmod = DEBUG_GetProcessMainModule(DEBUG_CurrProcess);
+    const char* pgm = (wmod) ? wmod->module_name : "none";
+
+    if (args) {
+	DEBUG_Printf(DBG_CHN_MESG, "Run (%s) with '%s'\n", pgm, args);
+    } else {
+	if (!DEBUG_LastCmdLine) {
+	    DEBUG_Printf(DBG_CHN_MESG, "Cannot find previously used command line.\n");
+	    return;
+	}
+	DEBUG_Start(DEBUG_LastCmdLine);
+    }
+}
+
 int DEBUG_main(int argc, char** argv)
 {
-    DWORD	pid = 0, retv = 0;
+    DWORD	retv = 0;
 
 #ifdef DBG_need_heap
     /* Initialize the debugger heap. */
@@ -641,66 +797,55 @@
     }
 
     DEBUG_Printf(DBG_CHN_MESG, "Starting WineDbg... ");
+
     if (argc == 3) {
 	HANDLE	hEvent;
+	DWORD	pid;
 
 	if ((pid = atoi(argv[1])) != 0 && (hEvent = atoi(argv[2])) != 0) {
-	    if (!(DEBUG_CurrProcess = DEBUG_AddProcess(pid, 0))) goto leave;
-	    DEBUG_CurrProcess->continue_on_first_exception = TRUE;
+	    BOOL	ret = DEBUG_Attach(pid, TRUE);
 
-	    if (!DebugActiveProcess(pid)) {
-		DEBUG_Printf(DBG_CHN_ERR, "Can't attach process %ld: %ld\n", 
-			     pid, GetLastError());
-		SetEvent(hEvent);
-		goto leave;
-	    }
 	    SetEvent(hEvent);
-	} else {
-	    pid = 0;
-	}
-    }
-    if (argc == 1) {
-	LPSTR	org, ptr;
-
-	DEBUG_Printf(DBG_CHN_MESG, "\n");
-	DEBUG_WalkProcess();
-	pid = strtol(org = readline("Enter pid to debug: "), &ptr, 0);
-	if (pid && ptr && ptr != org && *ptr == '\0') {
-	    if (!(DEBUG_CurrProcess = DEBUG_AddProcess(pid, 0))) goto leave;
-
-	    if (!DebugActiveProcess(pid)) {
+	    if (!ret) {
 		DEBUG_Printf(DBG_CHN_ERR, "Can't attach process %ld: %ld\n", 
-			     pid, GetLastError());
+			     DEBUG_CurrPid, GetLastError());
 		goto leave;
 	    }
-	} else {
-	    pid = 0;
+	    DEBUG_CurrPid = pid;
 	}
     }
 	
-    if (pid == 0) {
-	PROCESS_INFORMATION	info;
-	STARTUPINFOA		startup;
+    if (DEBUG_CurrPid == 0 && argc > 1) {
+	int	i, len;
+	LPSTR	cmdLine;
+		
+	if (!(cmdLine = DBG_alloc(len = 1))) goto oom_leave;
+	cmdLine[0] = '\0';
 
-	memset(&startup, 0, sizeof(startup));
-	startup.cb = sizeof(startup);
-	startup.dwFlags = STARTF_USESHOWWINDOW;
-	startup.wShowWindow = SW_SHOWNORMAL;
+	for (i = 1; i < argc; i++) {
+	    len += strlen(argv[i]) + 1;
+	    if (!(cmdLine = DBG_realloc(cmdLine, len))) goto oom_leave;
+	    strcat(cmdLine, argv[i]);
+	    cmdLine[len - 2] = ' ';
+	    cmdLine[len - 1] = '\0';
+	}
 
-	if (!CreateProcess(NULL, argv[1], NULL, NULL, 
-			   FALSE, DEBUG_PROCESS, NULL, NULL, &startup, &info)) {
-	    DEBUG_Printf(DBG_CHN_MESG, "Couldn't start process '%s'\n", argv[1]);
+	if (!DEBUG_Start(cmdLine)) {
+	    DEBUG_Printf(DBG_CHN_MESG, "Couldn't start process '%s'\n", cmdLine);
 	    goto leave;
 	}
-	pid = info.dwProcessId;
+	DBG_free(DEBUG_LastCmdLine);
+	DEBUG_LastCmdLine = cmdLine;
     }
 
-    if (pid) retv = DEBUG_MainLoop(pid);
+    retv = DEBUG_MainLoop();
  leave:
     /* saves modified variables */
     DEBUG_IntVarsRW(FALSE);
 
     return retv;
+
+ oom_leave:
+    DEBUG_Printf(DBG_CHN_MESG, "Out of memory\n");
+    goto leave;
 }
-
-