Index: stacklesseval.c
===================================================================
--- stacklesseval.c	(revision 88940)
+++ stacklesseval.c	(working copy)
@@ -84,7 +84,89 @@
     }
 }
 
+#ifdef _SEH32
+/// added by gil colgate 
+ struct EXCEPTION_REGISTRATION
+{
+    struct EXCEPTION_REGISTRATION* prev; // we start at the head, and go prev to go up the stack to the top. Ends in 0xfffffffff
+    FARPROC                 handler;
+};
+#define EXCEPTION_END  ((struct EXCEPTION_REGISTRATION *)0xFFFFFFFF)
+#define EXCEPTION_SAVED(x) ((struct EXCEPTION_REGISTRATION *)(x) !=  EXCEPTION_END)
+  
 
+/// added by gil colgate 
+#if DEBUG_SEH32
+void slp_debug_check_exeption_list(struct EXCEPTION_REGISTRATION *pVCExcRec)
+{
+    // will crash if exception list is bad, usually. This is the intention... 
+	// it's how the debug works. It will crash immediately if exception list is wrong rather than later.
+    // Walk the linked list of frames.  0xFFFFFFFF indicates the end of list
+        while ( EXCEPTION_END !=  pVCExcRec )
+        {
+            pVCExcRec = (pVCExcRec->prev);
+        }       
+}
+#endif
+ 
+/// added by gil colgate. In the normal case our program never calls this, I had to abuse our module
+/// files to get it to happen.
+void slp_patch_exception_list(struct EXCEPTION_REGISTRATION *pListToPatch, struct EXCEPTION_REGISTRATION  *patchPoint, DWORD stackPtrTop )
+{
+     if( pListToPatch ==   EXCEPTION_END) // I don't think this can happen
+        return;
+    if((DWORD)pListToPatch > stackPtrTop) // should not happen
+        return;
+
+    // Walk the linked list of frames.  0xFFFFFFFF indicates the end pListToPatchPrev list
+    while (  (DWORD)pListToPatch->prev < stackPtrTop)
+    {
+        pListToPatch =  (pListToPatch->prev);
+    }
+   
+    pListToPatch->prev = patchPoint;
+}
+
+
+/// added by gil colgate. In the normal case our program never calls this, I had to abuse our module
+/// files to get it to happen.
+struct EXCEPTION_REGISTRATION  *slp_get_exception_list_in_stack_above(struct EXCEPTION_REGISTRATION *pListToCheck,  DWORD stackPtrTop )
+{
+    // find the spot where we can reattach the list, not making any assumptions about the stack above us.
+    if(pListToCheck ==   EXCEPTION_END)  
+        return EXCEPTION_END;
+
+    // Walk the linked list of frames.  0xFFFFFFFF (EXCEPTION_END) indicates the end pListToPatchPrev list
+    while (  (DWORD)(pListToCheck) < stackPtrTop)
+    {
+        pListToCheck =  pListToCheck->prev;
+    }
+       
+    return pListToCheck;
+}
+
+// This is key to fixing the issue. Added by gil colgate
+DWORD slp_exception_to_save(intptr_t *stack)
+{
+    // save the exception list if we need to.
+    // We only need to if the stack area we are saving out
+    // contains an exception list. If the exception stack points
+    // higher up the stack into the code above the python calls
+    // we do not need to.
+
+    intptr_t *curExceptionList = (intptr_t *)  __readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList));
+
+    if(curExceptionList < stack)
+    {
+       return (DWORD)curExceptionList; // item we need to save
+    }
+    else
+    {
+        return  (DWORD)EXCEPTION_END; // no need to save, mark with -1
+    }
+}
+#endif
+
 PyCStackObject *
 slp_cstack_new(PyCStackObject **cst, intptr_t *stackref, PyTaskletObject *task)
 {
@@ -118,8 +200,11 @@
     (*cst)->nesting_level = ts->st.nesting_level;
 #ifdef _SEH32
     //save the SEH handler
-    (*cst)->exception_list = (DWORD)
-                __readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList));
+    #if DEBUG_SEH32
+     slp_debug_check_exeption_list((struct EXCEPTION_REGISTRATION *)__readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList)));
+    #endif
+     (*cst)->exception_list = slp_exception_to_save((*cst)->startaddr);
+     
 #endif
     return *cst;
 }
@@ -132,9 +217,11 @@
     memcpy((cstprev)->stack, (cstprev)->startaddr -
                              Py_SIZE(cstprev), stsizeb);
 #ifdef _SEH32
+   #if DEBUG_SEH32
+    slp_debug_check_exeption_list((struct EXCEPTION_REGISTRATION *)__readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList)));
+   #endif
+    (cstprev)->exception_list = slp_exception_to_save((cstprev)->startaddr);
     //save the SEH handler
-    cstprev->exception_list = (DWORD)
-                __readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList));
 #endif
     return stsizeb;
 }
@@ -145,14 +232,42 @@
 #endif
 slp_cstack_restore(PyCStackObject *cst)
 {
+
+#ifdef _SEH32
+    struct EXCEPTION_REGISTRATION *exList;
+    struct EXCEPTION_REGISTRATION * oldListStart;
+    if(EXCEPTION_SAVED( cst->exception_list))
+       oldListStart = slp_get_exception_list_in_stack_above((struct EXCEPTION_REGISTRATION * )__readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList)), (DWORD)cst->startaddr );
+    else if(slp_exception_to_save(cst->startaddr) != (DWORD)EXCEPTION_END)
+    {
+        // patch the old list if the new list is empty, and we have an old list.
+        oldListStart = slp_get_exception_list_in_stack_above((struct EXCEPTION_REGISTRATION * )__readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList)), (DWORD)cst->startaddr );
+        __writefsdword(FIELD_OFFSET(NT_TIB, ExceptionList), (DWORD)oldListStart);
+
+       #if DEBUG_SEH32
+        slp_debug_check_exeption_list((struct EXCEPTION_REGISTRATION *)__readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList)));
+       #endif
+    }
+#endif
+
     cst->tstate->st.nesting_level = cst->nesting_level;
     /* mark task as no longer responsible for cstack instance */
     cst->task = NULL;
     memcpy(cst->startaddr - Py_SIZE(cst), &cst->stack,
            Py_SIZE(cst) * sizeof(intptr_t));
 #ifdef _SEH32
-    //restore the SEH handler
-    __writefsdword(FIELD_OFFSET(NT_TIB, ExceptionList), (DWORD)(cst->exception_list));
+    //restore the SEH handler, if it was changed
+    if(EXCEPTION_SAVED(cst->exception_list))
+    {
+        __writefsdword(FIELD_OFFSET(NT_TIB, ExceptionList), (DWORD)(cst->exception_list));
+        exList = (struct EXCEPTION_REGISTRATION *)__readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList));
+        slp_patch_exception_list(exList, oldListStart, (DWORD)cst->startaddr );
+    }
+   
+   #if DEBUG_SEH32
+    slp_debug_check_exeption_list((struct EXCEPTION_REGISTRATION *)__readfsdword(FIELD_OFFSET(NT_TIB, ExceptionList)));
+   #endif
+
     #pragma warning(default:4733)
 #endif
 }
