[Stackless] Windows SEH problems and patch

Kristján Valur Jónsson kristjan at ccpgames.com
Tue Mar 27 15:52:58 CEST 2007


Just to elaborate on Richard's message:

Structured Exception Handling on win32 is managed by keeping a linked list of handlers.  C++ apparently
makes use of this to some extent, and so do various other pieces of library code.

It turned out that the fix is easy:  When creating the initials stub, store the current handler pointer.
Then save and restore this pointer along with the stack data.
This is not required on win64, since win64 has a standardized calling convention and stacks can be
Unwound without the help of a special handler.  The appropriate stack cleanup handler can be found by
association with the current function pointer.

Kristján

-----Original Message-----
From: stackless-bounces at stackless.com [mailto:stackless-bounces at stackless.com] On Behalf Of Richard Tew
Sent: 27. mars 2007 12:16
To: Stackless mailing list
Subject: [Stackless] Windows SEH problems and patch

Hi,

This email is just to record a patch which should be looked at for integration with the later versions of Python, most likely by myself.
Keep in mind that here at CCP we still use 2.3 and the version of Stackless which that had for anyone who takes a look at the patch.

What follows are Kristján Valur's notes on the problem for context, and the attached patch solves the problem.

"""
Until now, we have not been compiling our code with C exceptions enabled.  But now with VS2005, it is all but impossible to disable.

On windows, each thread has a Thread Information Block, accessible through the fs register:

typedef struct _NT_TIB {
    struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
    PVOID StackBase;
    PVOID StackLimit;
    PVOID SubSystemTib;
    union {
        PVOID FiberData;
        DWORD Version;
    };
    PVOID ArbitraryUserPointer;
    struct _NT_TIB *Self;
} NT_TIB;

typedef NT_TIB *PNT_TIB;

 it appears that C code register exception unwinding handlers in the ExceptionList.

I have a strange error on startup now and I think it is due to this:
C code that is switching stacks (by using PyChannel_Send(), etc)

will keep the same ExceptionList linked list of handlers after the stack switch, even though it makes no sense on the new stack.

Also, code that has registered a number of handlers, (through
recursion) may context switch to a different stack, which then

Proceeds to unwind, but will unwind the wrong handlers.  Clearly, each stack should have its own linked list of exception handlers.

 My idea would be to create a new TIB, which is a copy of the current TIB when a new tasklet is created (well, on the first hard switch.) In the new tasklet,

I would set up top level SEH (structured exception handlers) using the new TIB for the duration of the tasklet, and would then

Switch the fs register contents when there is a hard switch.

 I just am not certain where I should install my SEH handler.
Normally this is done with code like

__try {
                Run();
}
__catch (filter()) {
                ...
}

 But this means that I must guard a subroutine call...  I really don't want to start to manually insert handlers using compiler intrinsic... """

_______________________________________________
Stackless mailing list
Stackless at stackless.com
http://www.stackless.com/mailman/listinfo/stackless



More information about the Stackless mailing list