Uwe Bonnes wrote:

> I reversed Eric's patch and applied yours and now my crashing example
> shows:
> 
> fixme:dc:GetDCEx new hrgnClip[0000] smashes the previous[43b2]
> fixme:x11drv:error_handler BON:Xerror code 9
> Xlib: unexpected async reply (sequence 0x6c64)!
> fixme:seh:EXC_RtlRaiseException BON:res 1
> fixme:seh:EXC_RtlRaiseException BON:Stack 0x40c56c44 invalid
> fixme:seh:EXC_RtlRaiseException BON:signal_stack 0x40b41000 0x40b45000
> err:seh:EXC_DefaultHandling Exception frame is not in stack limits => unable to 
>dispatch exception.
> 
> and wine keeps hanging there.
> Those debugmsg with BON in it is added debug output.

Ok, the problem is that it goes up the exception chain and finds frames
that were posted while still on the old stack :-/  I don't think that
unwinding exceptions across stacks is a good idea;  what about the following
patch that simply catches all exceptions before they leave the large stack?

Bye,
Ulrich


diff -ur wine-cvs/include/callback.h wine-uw/include/callback.h
--- wine-cvs/include/callback.h Tue Apr 25 12:19:34 2000
+++ wine-uw/include/callback.h  Sun May 21 15:24:00 2000
@@ -12,20 +12,17 @@
 #include "wingdi.h"
 #include "wine/winuser16.h"
 
-extern int (*IF1632_CallLargeStack)( int (*func)(void), void *arg );
+extern void SYSDEPS_SwitchToThreadStack( void (*func)(void) ) WINE_NORETURN;
+extern int SYSDEPS_CallOnLargeStack( int (*func)(void *), void *arg );
 
-#define CALL_LARGE_STACK(func,arg) \
-    (IF1632_CallLargeStack ? \
-     IF1632_CallLargeStack( (int(*)())(func), (void *)(arg) ) : \
-     ((int(*)())(func))((void *)arg))
+#define CALL_LARGE_STACK( func, arg ) \
+        SYSDEPS_CallOnLargeStack( (int (*)(void *))(func), (void *)(arg) )
 
 typedef void (*RELAY)();
 extern FARPROC THUNK_Alloc( FARPROC16 func, RELAY relay );
 extern void THUNK_Free( FARPROC thunk );
 extern BOOL THUNK_Init(void);
 extern void THUNK_InitCallout(void);
-
-extern void CALL32_Init( void *func, void *target, void *stack ) WINE_NORETURN;
 
 typedef struct
 {
diff -ur wine-cvs/loader/task.c wine-uw/loader/task.c
--- wine-cvs/loader/task.c      Sun May 21 15:21:21 2000
+++ wine-uw/loader/task.c       Sun May 21 15:24:00 2000
@@ -43,8 +43,6 @@
   /* Min. number of thunks allocated when creating a new segment */
 #define MIN_THUNKS  32
 
-  /* Pointer to function to switch to a larger stack */
-int (*IF1632_CallLargeStack)( int (*func)(), void *arg ) = NULL;
 
 static THHOOK DefaultThhook = { 0 };
 THHOOK *pThhook = &DefaultThhook;
diff -ur wine-cvs/miscemu/main.c wine-uw/miscemu/main.c
--- wine-cvs/miscemu/main.c     Sat May  6 19:36:45 2000
+++ wine-uw/miscemu/main.c      Sun May 21 15:24:00 2000
@@ -124,8 +124,8 @@
     TASK_Reschedule();
 
     /* Switch stacks and jump to MAIN_EmulatorRun */
-    CALL32_Init( &IF1632_CallLargeStack, MAIN_EmulatorRun, NtCurrentTeb()->stack_top 
);
+    SYSDEPS_SwitchToThreadStack( MAIN_EmulatorRun );
 
-    MESSAGE( "main: Should never happen: returned from CALL32_Init()\n" );
+    MESSAGE( "main: Should never happen: returned from 
+SYSDEPS_SwitchToThreadStack()\n" );
     return 0;
 }
diff -ur wine-cvs/scheduler/process.c wine-uw/scheduler/process.c
--- wine-cvs/scheduler/process.c        Sat May  6 19:36:48 2000
+++ wine-uw/scheduler/process.c Sun May 21 15:24:00 2000
@@ -473,7 +473,7 @@
     SIGNAL_Init();  /* reinitialize signal stack */
 
     /* switch to the new stack */
-    CALL32_Init( &IF1632_CallLargeStack, start_process, NtCurrentTeb()->stack_top );
+    SYSDEPS_SwitchToThreadStack( start_process );
  error:
     ExitProcess( GetLastError() );
 }
@@ -522,7 +522,7 @@
     SIGNAL_Init();  /* reinitialize signal stack */
 
     /* switch to the new stack */
-    CALL32_Init( &IF1632_CallLargeStack, start_process, NtCurrentTeb()->stack_top );
+    SYSDEPS_SwitchToThreadStack( start_process );
  error:
     ExitProcess( GetLastError() );
 }
diff -ur wine-cvs/scheduler/sysdeps.c wine-uw/scheduler/sysdeps.c
--- wine-cvs/scheduler/sysdeps.c        Tue Apr 25 12:19:45 2000
+++ wine-uw/scheduler/sysdeps.c Sun May 21 17:34:19 2000
@@ -16,6 +16,7 @@
 #include <signal.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <sys/resource.h>
 #ifdef HAVE_SYS_SYSCALL_H
 # include <sys/syscall.h>
 #endif
@@ -218,6 +219,103 @@
      * but it eliminates a compiler warning.
      */
     exit( status );
+}
+
+
+/***********************************************************************
+ *           SYSDEPS_CallOnStack
+ */
+static int SYSDEPS_DoCallOnStack( int (*func)(LPVOID), LPVOID arg ) WINE_UNUSED;
+static int SYSDEPS_DoCallOnStack( int (*func)(LPVOID), LPVOID arg )
+{
+    int retv = 0;
+
+    __TRY
+    {
+        retv = func( arg );
+    }
+    __EXCEPT(UnhandledExceptionFilter)
+    {
+        TerminateThread( GetCurrentThread(), GetExceptionCode() );
+        return 0;
+    }
+    __ENDTRY
+
+    return retv;
+}
+
+#ifdef __i386__
+int SYSDEPS_CallOnStack( LPVOID stackTop, LPVOID stackLow,
+                         int (*func)(LPVOID), LPVOID arg );
+__ASM_GLOBAL_FUNC( SYSDEPS_CallOnStack,
+                   "pushl %ebp\n\t"
+                   "movl %esp, %ebp\n\t"
+                   ".byte 0x64; pushl 0x04\n\t"
+                   ".byte 0x64; pushl 0x08\n\t"
+                   "movl 8(%ebp), %esp\n\t"
+                   "movl 12(%ebp), %eax\n\t"
+                   ".byte 0x64; movl %esp, 0x04\n\t"
+                   ".byte 0x64; movl %eax, 0x08\n\t"
+                   "pushl 20(%ebp)\n\t"
+                   "pushl 16(%ebp)\n\t"
+                   "call " __ASM_NAME("SYSDEPS_DoCallOnStack") "\n\t"
+                   "leal -8(%ebp), %esp\n\t"
+                   ".byte 0x64; popl 0x08\n\t"
+                   ".byte 0x64; popl 0x04\n\t"
+                   "popl %ebp\n\t"
+                   "ret" );
+#else
+int SYSDEPS_CallOnStack( LPVOID stackTop, LPVOID stackLow,
+                         int (*func)(LPVOID), LPVOID arg )
+{
+    return func( arg );
+}
+#endif
+
+/***********************************************************************
+ *           SYSDEPS_SwitchToThreadStack
+ */
+
+static LPVOID SYSDEPS_LargeStackTop = NULL;
+static LPVOID SYSDEPS_LargeStackLow = NULL;
+
+void SYSDEPS_SwitchToThreadStack( void (*func)(void) )
+{
+    TEB *teb = NtCurrentTeb();
+    LPVOID stackTop = teb->stack_top;
+    LPVOID stackLow = teb->stack_low;
+
+    struct rlimit rl;
+
+    if ( getrlimit(RLIMIT_STACK, &rl) < 0 ) 
+    {
+        WARN("Can't get rlimit\n");
+        rl.rlim_cur = 8*1024*1024;
+    }
+
+    SYSDEPS_LargeStackTop = teb->stack_top = &func - 128;
+    SYSDEPS_LargeStackLow = teb->stack_low = teb->stack_top - rl.rlim_cur;
+
+    SYSDEPS_CallOnStack( stackTop, stackLow, 
+                         (int (*)(void *))func, NULL );
+}
+
+/***********************************************************************
+ *           SYSDEPS_CallOnLargeStack
+ */
+int SYSDEPS_CallOnLargeStack( int (*func)(LPVOID), LPVOID arg )
+{
+    static int recurse = 0;
+    int retv;
+
+    if ( recurse++ == 0 && SYSDEPS_LargeStackTop )
+        retv = SYSDEPS_CallOnStack( SYSDEPS_LargeStackTop,
+                                    SYSDEPS_LargeStackLow, func, arg );
+    else
+        retv = func( arg );
+
+    recurse--;
+    return retv;
 }
 
 
diff -ur wine-cvs/tools/build.c wine-uw/tools/build.c
--- wine-cvs/tools/build.c      Sun May 21 15:21:23 2000
+++ wine-uw/tools/build.c       Sun May 21 15:24:00 2000
@@ -2845,101 +2845,6 @@
 }
 
 
-/*******************************************************************
- *         BuildCallTo32LargeStack
- *
- * Build the function used to switch to the original 32-bit stack
- * before calling a 32-bit function from 32-bit code. This is used for
- * functions that need a large stack, like X bitmaps functions.
- *
- * The generated function has the following prototype:
- *   int xxx( int (*func)(), void *arg );
- *
- * The pointer to the function can be retrieved by calling CALL32_Init,
- * which also takes care of saving the current 32-bit stack pointer.
- * Furthermore, CALL32_Init switches to a new stack and jumps to the
- * specified target address.
- *
- * NOTE: The CALL32_LargeStack routine may be recursively entered by the 
- *       same thread, but not concurrently entered by several threads.
- *
- * Stack layout of CALL32_Init:
- *
- * (esp+12)  new stack address
- * (esp+8)   target address
- * (esp+4)   pointer to variable to receive CALL32_LargeStack address
- * (esp)     ret addr
- *
- * Stack layout of CALL32_LargeStack:
- *   ...     ...
- * (ebp+12)  arg
- * (ebp+8)   func
- * (ebp+4)   ret addr
- * (ebp)     ebp
- */
-static void BuildCallTo32LargeStack( FILE *outfile )
-{
-    /* Initialization function */
-
-    fprintf( outfile, "\n\t.align 4\n" );
-#ifdef USE_STABS
-    fprintf( outfile, ".stabs \"CALL32_Init:F1\",36,0,0," PREFIX "CALL32_Init\n");
-#endif
-    fprintf( outfile, "\t.globl " PREFIX "CALL32_Init\n" );
-    fprintf( outfile, "\t.type " PREFIX "CALL32_Init,@function\n" );
-    fprintf( outfile, PREFIX "CALL32_Init:\n" );
-    fprintf( outfile, "\tmovl %%esp,CALL32_Original32_esp\n" );
-    fprintf( outfile, "\tpopl %%eax\n" );
-    fprintf( outfile, "\tpopl %%eax\n" );
-    fprintf( outfile, "\tmovl $CALL32_LargeStack,(%%eax)\n" );
-    fprintf( outfile, "\tpopl %%eax\n" );
-    fprintf( outfile, "\tpopl %%esp\n" );
-    fprintf( outfile, "\tpushl %%eax\n" );
-    fprintf( outfile, "\tret\n" );
-
-    /* Function header */
-
-    fprintf( outfile, "\n\t.align 4\n" );
-#ifdef USE_STABS
-    fprintf( outfile, ".stabs \"CALL32_LargeStack:F1\",36,0,0,CALL32_LargeStack\n");
-#endif
-    fprintf( outfile, "CALL32_LargeStack:\n" );
-    
-    /* Entry code */
-
-    fprintf( outfile, "\tpushl %%ebp\n" );
-    fprintf( outfile, "\tmovl %%esp,%%ebp\n" );
-
-    /* Switch to the original 32-bit stack pointer */
-
-    fprintf( outfile, "\tcmpl $0, CALL32_RecursionCount\n" );
-    fprintf( outfile, "\tjne  CALL32_skip\n" );
-    fprintf( outfile, "\tmovl CALL32_Original32_esp, %%esp\n" );
-    fprintf( outfile, "CALL32_skip:\n" );
-
-    fprintf( outfile, "\tincl CALL32_RecursionCount\n" );
-
-    /* Transfer the argument and call the function */
-
-    fprintf( outfile, "\tpushl 12(%%ebp)\n" );
-    fprintf( outfile, "\tcall *8(%%ebp)\n" );
-
-    /* Restore registers and return */
-
-    fprintf( outfile, "\tdecl CALL32_RecursionCount\n" );
-
-    fprintf( outfile, "\tmovl %%ebp,%%esp\n" );
-    fprintf( outfile, "\tpopl %%ebp\n" );
-    fprintf( outfile, "\tret\n" );
-
-    /* Data */
-
-    fprintf( outfile, "\t.data\n" );
-    fprintf( outfile, "CALL32_Original32_esp:\t.long 0\n" );
-    fprintf( outfile, "CALL32_RecursionCount:\t.long 0\n" );
-    fprintf( outfile, "\t.text\n" );
-}
-
 
 /*******************************************************************
  *         BuildCallFrom32Regs
@@ -3268,10 +3173,6 @@
         fprintf( outfile, "Code_Start:\n" );
     }
 #endif
-
-    /* Build the 32-bit large stack callback */
-
-    BuildCallTo32LargeStack( outfile );
 
     /* Build the register callback function */
 


-- 
  Dr. Ulrich Weigand
  [EMAIL PROTECTED]

Reply via email to