Ignore:
Timestamp:
Jul 5, 2011, 7:52:42 PM (14 years ago)
Author:
dmik
Message:

kernel32: SEH: Disabled unwinding Win32 exception handlers in response to the OS/2 unwind procedure to prevent endless recursive crashes inside OS2RtlUnwind() happening due to stack corruption under SMP kernel when too many threads are being unwound at once. Closes #37.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/seh/sehutil.s

    r21645 r21662  
    4949    jne ___seh_handler_Win32 /* No, assume the Win32 chain */
    5050
     51    /* Note: Unwinding is disabled here since a) it is more correct to do
     52     * centralized unwinding from OS2ExceptionHandler2ndLevel() (i.e. not only
     53     * for SEH frames) and b) it crashes under SMP kernel due to stack being
     54     * corrupt by the time when unwinding happens. See comments in
     55     * OS2ExceptionHandler2ndLevel() for more details. */
     56
     57#if 0
     58
    5159    movl 8(%ebp), %eax
    5260    movl 4(%eax), %eax /* fHandlerFlags */
     
    6472___seh_handler_OS2_Unwind:
    6573
     74    /* unwind the Win32 chain including our frame as someone's definitely
     75     * jumping outside it if we're being unwound by OS/2 */
     76    movl 12(%ebp), %eax
     77    cmpl $0, 64(%eax)                   /* Win32FS == 0? */
     78    je ___seh_handler_OS2_Unwind_End    /* Yes, we already unwound this frame */
     79
    6680    /* restore the Win32 chain in our frame */
    67     movl 12(%ebp), %eax
    6881    movl 60(%eax), %ebx /* pPrevFrameWin32 */
    6982    movl %ebx, 0(%eax)  /* pPrev */
    7083
    71     /* unwind the Win32 chain including our frame as someone's definitely
    72      * jumping outside it if we're being unwound */
    7384    pushl %fs
    7485
     
    89100    movl %ecx, 0(%eax)  /* pPrev */
    90101
     102___seh_handler_OS2_Unwind_End:
     103
    91104    xor %eax, %eax  /* return code is irrelevant for EH_UNWINDING */
    92105    jmp ___seh_handler_Return
     106
     107#else
     108
     109    /* restore the OS/2 chain in our frame */
     110    movl 12(%ebp), %eax
     111    movl 44(%eax), %ecx /* pPrevFrameOS2 */
     112    movl %ecx, 0(%eax)  /* pPrev */
     113
     114    xorl %eax, %eax  /* return XCPT_CONTINUE_SEARCH (0) */
     115    jmp ___seh_handler_Return
     116
     117#endif
    93118
    94119___seh_handler_Win32:
     
    101126    /* skip EH_UNWINDING calls (for compatibility with MSVC) */
    102127    movl 8(%ebp), %ebx
    103     movl 4(%ebx), %eax /* pRec->ExceptionFlags */
    104     testl $0x2, %eax /* EH_UNWINDING? */
     128    movl 4(%ebx), %eax                      /* pRec->ExceptionFlags */
     129    testl $0x2, %eax                        /* EH_UNWINDING? */
     130    je ___seh_handler_Win32_NotUnwinding    /* No, continue normally */
     131
     132    /* See the comment above */
     133#if 0
     134    /* clear out the Win32FS field so that we will not attempt to unwind twice
     135     * (first, as a result of forced unwind from ExitProcess/ExitThread/etc and
     136     * then from the OS/2 EH_UNWINDING call of our handler) */
     137    movl 12(%ebp), %eax
     138    movl $0, 64(%eax)   /* Win32FS */
     139#endif
     140
    105141    movl $1, %eax /* ExceptionContinueSearch */
    106     jne ___seh_handler_Return
     142    jmp ___seh_handler_Return
     143
     144___seh_handler_Win32_NotUnwinding:
    107145
    108146    /* save handler's context */
Note: See TracChangeset for help on using the changeset viewer.