From 7d43bceb7e7e63fcc7180588a0bfca183eb2625c Mon Sep 17 00:00:00 2001
From: Ulrich Weigand <weigand@informatik.uni-erlangen.de>
Date: Sun, 30 Jan 2000 21:16:45 +0000
Subject: [PATCH] Moved debugger to libwine to make it available to WineLib
 apps. Try to invoke external debugger if internal debugger crashes. Try to
 handle early invocation of debugger more gracefully.

---
 Makefile.in              |  4 ++--
 debugger/dbg.y           | 21 ++++++++++++++-------
 debugger/external.c      | 10 +++++-----
 dlls/ntdll/exception.c   | 35 +++--------------------------------
 include/debugger.h       |  3 +++
 include/thread.h         |  2 +-
 include/wine/exception.h |  3 ---
 miscemu/main.c           |  6 +-----
 win32/except.c           |  5 +++--
 9 files changed, 32 insertions(+), 57 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index 636507ee1a6..f5ebbd1654c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -34,6 +34,7 @@ TOOLSUBDIRS = \
 LIBSUBDIRS = \
 	controls \
 	console \
+	debugger \
 	dlls/advapi32 \
 	dlls/avifil32 \
 	dlls/comctl32 \
@@ -115,7 +116,6 @@ X11SUBDIRS = \
 	windows/x11drv
 
 EMUSUBDIRS = \
-	debugger \
 	miscemu \
 	server
 
@@ -154,6 +154,7 @@ CLEANSUBDIRS = dlls include include/bitmaps include/wine
 LIBOBJS = \
 	controls/controls.o \
 	console/console.o \
+	debugger/debugger.o \
 	dlls/advapi32/advapi32.o \
 	dlls/avifil32/avifil32.o \
 	dlls/comctl32/comctl32.o \
@@ -234,7 +235,6 @@ X11OBJS = \
 	windows/x11drv/x11drv.o
 
 EMUOBJS = \
-	debugger/debugger.o \
 	miscemu/miscemu.o
 
 EXTRA_OBJS = $(LIBOBJS) $(X11OBJS)
diff --git a/debugger/dbg.y b/debugger/dbg.y
index 96c6c7bb8e8..663a4e3bb6b 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -423,10 +423,16 @@ static void DEBUG_Freeze( BOOL freeze )
 
     if ( freeze && !frozen )
     {
-        /* Don't freeze thread currently holding the X crst! */
-        EnterCriticalSection( &X11DRV_CritSection );
-        CLIENT_DebuggerRequest( DEBUGGER_FREEZE_ALL );
-        LeaveCriticalSection( &X11DRV_CritSection );
+        if ( X11DRV_CritSection.LockSemaphore )
+        {
+            /* Don't freeze thread currently holding the X crst! */
+            EnterCriticalSection( &X11DRV_CritSection );
+            CLIENT_DebuggerRequest( DEBUGGER_FREEZE_ALL );
+            LeaveCriticalSection( &X11DRV_CritSection );
+        }
+        else
+            CLIENT_DebuggerRequest( DEBUGGER_FREEZE_ALL );
+
         frozen = TRUE;
     }
 
@@ -468,7 +474,8 @@ static void DEBUG_Main( BOOL is_debug )
 
     if (in_debugger)
     {
-        fprintf( stderr, " inside debugger, exiting.\n" );
+        fprintf( stderr, " inside debugger, trying to invoke external debugger.\n" );
+        DEBUG_ExternalDebugger();
         DEBUG_Exit(1);
     }
     in_debugger = TRUE;
@@ -554,7 +561,7 @@ static void DEBUG_Main( BOOL is_debug )
         DEBUG_Freeze( TRUE );
 
         /* Put the display in a correct state */
-	USER_Driver->pBeginDebugging();
+	if (USER_Driver) USER_Driver->pBeginDebugging();
 
 #ifdef __i386__
         newmode = ISV86(&DEBUG_context) ? 16 : IS_SELECTOR_32BIT(addr.seg) ? 32 : 16;
@@ -633,7 +640,7 @@ static void DEBUG_Main( BOOL is_debug )
 
     in_debugger = FALSE;
 
-    USER_Driver->pEndDebugging();
+    if (USER_Driver) USER_Driver->pEndDebugging();
 }
 
 
diff --git a/debugger/external.c b/debugger/external.c
index fb3deec2862..95c72ca4174 100644
--- a/debugger/external.c
+++ b/debugger/external.c
@@ -14,7 +14,7 @@
 #include <stdio.h>
 #include <string.h>
 
-
+#include "options.h"
 
 #define DBG_BUFF_SIZE  12
 
@@ -90,9 +90,9 @@ void DEBUG_ExternalDebugger(void)
   if (child_pid == 0)
   {
     int  status;
-    char *dbg_external;
-    char *dbg_wine_location;
-    char *dbg_no_xterm;
+    const char *dbg_external;
+    const char *dbg_wine_location;
+    const char *dbg_no_xterm;
     char pid_string[DBG_BUFF_SIZE];    
 
 
@@ -107,7 +107,7 @@ void DEBUG_ExternalDebugger(void)
 
     /* if not set in environment, use default */
     if (!dbg_wine_location)
-      dbg_wine_location = "/usr/local/bin/wine";
+      dbg_wine_location = argv0;
 
     /* check for empty string in WINE_DBG_NO_XTERM */
     if (dbg_no_xterm && (strlen(dbg_no_xterm) < 1))
diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c
index ba94e191b6d..fe40166bcf6 100644
--- a/dlls/ntdll/exception.c
+++ b/dlls/ntdll/exception.c
@@ -13,6 +13,7 @@
 #include "wine/exception.h"
 #include "stackframe.h"
 #include "miscemu.h"
+#include "debugger.h"
 #include "debugtools.h"
 
 DEFAULT_DEBUG_CHANNEL(seh)
@@ -25,36 +26,6 @@ typedef struct
 } EXC_NESTED_FRAME;
 
  
-/* Default hook for built-in debugger */
-static DWORD default_hook( EXCEPTION_RECORD *rec, CONTEXT *ctx, BOOL first )
-{
-    if (!first)
-    {
-    	DPRINTF( "stopping process due to unhandled exception %08lx.\n",
-                 rec->ExceptionCode );
-	raise( SIGSTOP );
-    }
-    return 0;  /* not handled */
-}
-static DEBUGHOOK debug_hook = default_hook;
-
-/*******************************************************************
- *         EXC_SetDebugEventHook
- *         EXC_GetDebugEventHook
- *
- * Set/Get the hook for the built-in debugger.
- *
- * FIXME: the built-in debugger should use the normal debug events.
- */
-void EXC_SetDebugEventHook( DEBUGHOOK hook )
-{
-    debug_hook = hook;
-}
-DEBUGHOOK EXC_GetDebugEventHook(void)
-{
-    return debug_hook;
-}
-
 /*******************************************************************
  *         EXC_RaiseHandler
  *
@@ -125,7 +96,7 @@ static void EXC_DefaultHandling( EXCEPTION_RECORD *rec, CONTEXT *context )
         (DEBUG_SendExceptionEvent( rec, FALSE, context ) == DBG_CONTINUE))
         return;  /* continue execution */
 
-    if (debug_hook( rec, context, FALSE ) == DBG_CONTINUE)
+    if (wine_debugger( rec, context, FALSE ) == DBG_CONTINUE)
         return;  /* continue execution */
 
     if (rec->ExceptionFlags & EH_STACK_INVALID)
@@ -155,7 +126,7 @@ void WINAPI EXC_RtlRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context )
         (DEBUG_SendExceptionEvent( rec, TRUE, context ) == DBG_CONTINUE))
         return;  /* continue execution */
 
-    if (debug_hook( rec, context, TRUE ) == DBG_CONTINUE)
+    if (wine_debugger( rec, context, TRUE ) == DBG_CONTINUE)
         return;  /* continue execution */
 
     frame = NtCurrentTeb()->except;
diff --git a/include/debugger.h b/include/debugger.h
index f79dd2d1748..7bbc97afca8 100644
--- a/include/debugger.h
+++ b/include/debugger.h
@@ -325,6 +325,9 @@ extern void DEBUG_NukePath(void);
 extern void DEBUG_GetCurrentAddress( DBG_ADDR * );
 extern void DEBUG_Disassemble( const DBG_ADDR *, const DBG_ADDR*, int offset );
 
+  /* debugger/external.c */
+extern void DEBUG_ExternalDebugger(void);
+
   /* debugger/dbg.y */
 extern DWORD wine_debugger( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance );
 extern void DEBUG_Exit( DWORD exit_code );
diff --git a/include/thread.h b/include/thread.h
index e1813b465ff..70c82c42898 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -63,7 +63,7 @@ typedef struct _TEB
     void        *signal_stack;   /* --3  58 Signal stack (was: exit_stack) */
     void        *emu_data;       /* --n  5c Related to 80387 emulation */
     DWORD        last_error;     /* 1--  60 Last error code */
-    HANDLE       event;          /* --3  64 Thread event (was: debugger context block) */
+    HANDLE       debug_cb;       /* 1-n  64 Debugger context block */
     DWORD        debug_thread;   /* 1-n  68 Thread debugging this one (?) */
     void        *pcontext;       /* 1-n  6c Thread register context */
     DWORD        cur_stack;      /* --3  70 Current stack (was: unknown) */
diff --git a/include/wine/exception.h b/include/wine/exception.h
index bfbe6940fbe..d184de9d51d 100644
--- a/include/wine/exception.h
+++ b/include/wine/exception.h
@@ -172,9 +172,6 @@ extern void WINAPI EXC_RtlUnwind( PEXCEPTION_FRAME, LPVOID,
                                   PEXCEPTION_RECORD, DWORD, CONTEXT * );
 extern void WINAPI EXC_DebugBreak( CONTEXT *context );
 
-typedef DWORD (*DEBUGHOOK)( EXCEPTION_RECORD *, CONTEXT *, BOOL );
-extern void EXC_SetDebugEventHook( DEBUGHOOK hook );
-extern DEBUGHOOK EXC_GetDebugEventHook(void);
 extern BOOL SIGNAL_Init(void);
 #endif
 
diff --git a/miscemu/main.c b/miscemu/main.c
index 675826d8694..566ed6f122e 100644
--- a/miscemu/main.c
+++ b/miscemu/main.c
@@ -108,12 +108,8 @@ int main( int argc, char *argv[] )
 {
     NE_MODULE *pModule;
 
-    /* Set up debugger hook */
-    EXC_SetDebugEventHook( wine_debugger );
-    TASK_AddTaskEntryBreakpoint = DEBUG_AddTaskEntryBreakpoint;
-
     /* Initialize everything */
-    if (!MAIN_MainInit( &argc, argv )) return 1;
+    if (!MAIN_MainInit( &argc, argv, FALSE )) return 1;
     MAIN_argc = argc; MAIN_argv = argv;
 
     /* Create initial task */
diff --git a/win32/except.c b/win32/except.c
index be6ee2b3a09..75cb02efe9a 100644
--- a/win32/except.c
+++ b/win32/except.c
@@ -31,6 +31,7 @@
 #include "process.h"
 #include "thread.h"
 #include "stackframe.h"
+#include "debugger.h"
 #include "debugtools.h"
 
 DEFAULT_DEBUG_CHANNEL(seh)
@@ -78,8 +79,8 @@ DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers)
     }
 
     /* FIXME: does not belong here */
-    if (((*EXC_GetDebugEventHook())( epointers->ExceptionRecord,
-                                     epointers->ContextRecord, FALSE )) == DBG_CONTINUE)
+    if (wine_debugger( epointers->ExceptionRecord,
+                       epointers->ContextRecord, FALSE ) == DBG_CONTINUE)
         return EXCEPTION_CONTINUE_EXECUTION;
 
     /* FIXME: Should check the current error mode */
-- 
GitLab