Ignore:
Timestamp:
Apr 18, 2012, 10:46:37 PM (13 years ago)
Author:
dmik
Message:

kernel32: Make SEH work in OS/2 context.

See #82 for details.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/exceptions.cpp

    r21980 r21999  
    120120                             PCONTEXTRECORD pCtxRec, PVOID p, PSZ szTrapDump);
    121121
    122 int __cdecl __seh_handler(PWINEXCEPTION_RECORD pRec,
    123                           PWINEXCEPTION_FRAME pFrame,
    124                           PCONTEXTRECORD pContext, PVOID pVoid);
    125 
    126 PWINEXCEPTION_FRAME __cdecl __seh_get_prev_frame(PWINEXCEPTION_FRAME pFrame);
     122int __cdecl __seh_handler(PVOID pRec, PVOID pFrame,
     123                          PVOID pContext, PVOID pVoid);
     124
     125int __cdecl __seh_handler_win32(PWINEXCEPTION_RECORD pRec,
     126                                PWINEXCEPTION_FRAME pFrame,
     127                                PCONTEXTRECORD pContext, PVOID pVoid);
     128
     129PWINEXCEPTION_FRAME __cdecl __seh_get_prev_frame_win32(PWINEXCEPTION_FRAME pFrame);
    127130
    128131#ifdef DEBUG
     
    363366    while( (pFrame != NULL) && ((ULONG)((ULONG)pFrame & 0xFFFFF000) != 0xFFFFF000) )
    364367    {
    365         pPrevFrame = __seh_get_prev_frame(pFrame);
     368        pPrevFrame = __seh_get_prev_frame_win32(pFrame);
    366369
    367370        dprintf(("KERNEL32: RtlDispatchException - pframe=%08X, pframe->Prev=%08X",
     
    518521  while (((ULONG)((ULONG)frame & 0xFFFFF000) != 0xFFFFF000) && (frame != pEndFrame))
    519522  {
    520         prevFrame = __seh_get_prev_frame(frame);
     523        prevFrame = __seh_get_prev_frame_win32(frame);
    521524
    522525        /* Check frame address */
     
    590593        dprintf(("KERNEL32: RtlUnwind (after) - frame=%08X, frame->Prev=%08X", frame,
    591594                 ((ULONG)((ULONG)frame & 0xFFFFF000) != 0xFFFFF000) ?
    592                  __seh_get_prev_frame(frame) : (void*)0xFFFFFFFF));
     595                 __seh_get_prev_frame_win32(frame) : (void*)0xFFFFFFFF));
    593596  }
    594597
     
    12421245                                           PVOID                        p)
    12431246{
     1247    // we need special processing when reused from ___seh_handler
     1248    BOOL fSEH = pERegRec->ExceptionHandler == (_ERR *)__seh_handler;
     1249
    12441250#ifdef DEBUG
    12451251    //SvL: Check if exception inside debug fprintf -> if so, clear lock so
     
    12791285        if (pERepRec->fHandlerFlags & EH_EXIT_UNWIND)
    12801286        {
    1281             dprintf(("KERNEL32: OS2ExceptionHandler: EH_EXIT_UNWIND, "
    1282                      "unwinding all the Win32 exception chain"));
     1287            dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): EH_EXIT_UNWIND, "
     1288                     "unwinding all the Win32 exception chain", fSEH));
    12831289            RtlUnwind(NULL, 0, 0, 0);
    12841290        }
    12851291        else
    12861292        {
    1287             dprintf(("KERNEL32: OS2ExceptionHandler: EH_UNWINDING, "
    1288                      "unwinding the Win32 exception chain up to 0x%p", pERegRec));
     1293            dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): EH_UNWINDING, "
     1294                     "unwinding the Win32 exception chain up to 0x%p", fSEH, pERegRec));
    12891295
    12901296            // find a Win32 exception frame closest to the OS/2 one (pERegRec)
     
    12951301            while (frame != NULL && ((ULONG)frame)!= 0xFFFFFFFF &&
    12961302                   ((ULONG)frame) <= ((ULONG)pERegRec))
    1297                 frame = __seh_get_prev_frame(frame);
     1303                frame = __seh_get_prev_frame_win32(frame);
    12981304            if (((ULONG)frame) == 0xFFFFFFFF)
    12991305                frame = NULL;
     
    13161322    case XCPT_FLOAT_UNDERFLOW:
    13171323        dprintfException(pERepRec, pERegRec, pCtxRec, p);
    1318         dprintf(("KERNEL32: OS2ExceptionHandler: FPU exception\n"));
    1319         if((!fIsOS2Image || fSEHEnabled) && !fExitProcess)  //Only for real win32 apps or if SEH enabled
    1320         {
    1321             if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p) == FALSE)
     1324        dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): FPU exception\n", fSEH));
     1325        if((!fIsOS2Image || fForceWin32TIB || fSEH) && !fExitProcess)  //Only for real win32 apps or when forced
     1326        {
     1327            if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p, fSEH) == FALSE)
    13221328            {
    13231329                pCtxRec->ctx_env[0] |= 0x1F;
     
    13281334            else
    13291335            {
    1330                 dprintf(("KERNEL32: OS2ExceptionHandler: fix and continue\n"));
     1336                dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): fix and continue\n", fSEH));
    13311337                goto continueexecution;
    13321338            }
    13331339        }
    1334         dprintf(("KERNEL32: OS2ExceptionHandler: continue search\n"));
     1340        dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): continue search\n", fSEH));
    13351341        goto continuesearch;
    13361342
     
    14391445        DosQueryMem((PVOID) pERepRec->ExceptionInfo[1],
    14401446                    &offset, &accessflag);
    1441         dprintf(("KERNEL32: OS2ExceptionHandler: failed address info 0x%X size 0x%X. flag %X\n",
    1442                  pERepRec->ExceptionInfo[1], offset, accessflag));
     1447        dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): failed address info 0x%X size 0x%X. flag %X\n",
     1448                 fSEH, pERepRec->ExceptionInfo[1], offset, accessflag));
    14431449        /* check for valid address */
    14441450        if (!pERepRec->ExceptionInfo[1] ||
     
    14541460                             offset + (pERepRec->ExceptionInfo[1] - (pERepRec->ExceptionInfo[1] & 0xFFFFF000)),
    14551461                  accessflag | PAG_WRITE | PAG_COMMIT);
    1456         dprintf(("KERNEL32: OS2ExceptionHandler: commiting 0x%X size 0x%X. RC: %i\n",
    1457                  pERepRec->ExceptionInfo[1] & 0xFFFFF000,
     1462        dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): commiting 0x%X size 0x%X. RC: %i\n",
     1463                 fSEH, pERepRec->ExceptionInfo[1] & 0xFFFFF000,
    14581464                 offset + (pERepRec->ExceptionInfo[1] - (pERepRec->ExceptionInfo[1] & 0xFFFFF000)),
    14591465                           rc));
     
    15081514
    15091515                //NOTE: This will not work properly in case multiple threads execute this code
    1510                 dprintf(("Changing thread registers (SetThreadContext)!!"));
     1516                dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): Changing thread registers (SetThreadContext)!!", fSEH));
    15111517
    15121518                if(teb->o.odin.context.ContextFlags & WINCONTEXT_CONTROL) {
     
    15831589#endif
    15841590
    1585         if((!fIsOS2Image || fSEHEnabled) && !fExitProcess)  //Only for real win32 apps or if SEH enabled
    1586         {
    1587             if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p) == TRUE)
     1591        if((!fIsOS2Image || fForceWin32TIB || fSEH) && !fExitProcess)  //Only for real win32 apps or when forced
     1592        {
     1593            if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p, fSEH) == TRUE)
    15881594            {
    1589                 dprintf(("KERNEL32: OS2ExceptionHandler: fix and continue\n"));
     1595                dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): fix and continue\n", fSEH));
    15901596                goto continueexecution;
    15911597            }
    15921598            else
    15931599            {
    1594                 dprintf(("KERNEL32: OS2ExceptionHandler: continue search\n"));
     1600                dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): continue search\n", fSEH));
    15951601                goto continuesearch;
    15961602            }
     
    16051611                if(rc == NO_ERROR)
    16061612                {
    1607                     dprintf(("KERNEL32: OS2ExceptionHandler: Continue and kill thread"));
     1613                    dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): Continue and kill thread", fSEH));
    16081614
    16091615                    pCtxRec->ctx_RegEip = (pTIB->tib_ptib2->tib2_ultid != 1) ? (ULONG)KillWin32Thread : (ULONG)KillWin32Process;
     
    16201626        logException(pERepRec, pERegRec, pCtxRec, p);
    16211627
    1622         dprintf(("KERNEL32: OS2ExceptionHandler: Continue and kill\n"));
     1628        dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): Continue and kill\n", fSEH));
    16231629
    16241630        pCtxRec->ctx_RegEip = (ULONG)KillWin32Process;
     
    16481654
    16491655        // Make sure we detect a stack overflow condition before the system does
    1650         if ((!fIsOS2Image || fSEHEnabled) && //Only for real win32 apps or if SEH enabled
     1656        if ((!fIsOS2Image || fForceWin32TIB || fSEH) && //Only for real win32 apps or when forced
    16511657            pERepRec->ExceptionInfo[1]  >= stackbottom &&
    16521658            pERepRec->ExceptionInfo[1]  <  stacktop
     
    17041710                    recoutofstack.cParameters   = 0;
    17051711
    1706                     if(OSLibDispatchException(&recoutofstack, pERegRec, pCtxRec, p) == TRUE)
     1712                    if(OSLibDispatchException(&recoutofstack, pERegRec, pCtxRec, p, fSEH) == TRUE)
    17071713                    {
    17081714                        goto continueexecution;
     
    17141720        {
    17151721            // Throw EXCEPTION_GUARD_PAGE_VIOLATION in the Win32 context
    1716             if((!fIsOS2Image || fSEHEnabled) && !fExitProcess)  //Only for real win32 apps or if SEH enabled
     1722            if((!fIsOS2Image || fForceWin32TIB || fSEH) && !fExitProcess)  //Only for real win32 apps or when forced
    17171723            {
    1718                 if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p) == TRUE)
     1724                if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p, fSEH) == TRUE)
    17191725                {
    17201726                    goto continueexecution;
     
    19611967    while ((pFrame != NULL) && ((ULONG)pFrame != 0xFFFFFFFF))
    19621968    {
    1963         PWINEXCEPTION_FRAME pPrevFrame = __seh_get_prev_frame(pFrame);
     1969        PWINEXCEPTION_FRAME pPrevFrame = __seh_get_prev_frame_win32(pFrame);
    19641970        dprintf(("  Record at %08X, Prev at %08X, handler at %08X%s",
    19651971                 pFrame, pPrevFrame, pFrame->Handler,
    1966                  pFrame->Handler == (PEXCEPTION_HANDLER)__seh_handler ?
    1967                  " (SEH)" : ""));
     1972                 pFrame->Handler == (PEXCEPTION_HANDLER)__seh_handler ? " (SEH)" :
     1973                 pFrame->Handler == (PEXCEPTION_HANDLER)__seh_handler_win32 ? " (SEH Win32)" : ""));
    19681974        if (pFrame == pPrevFrame)
    19691975        {
Note: See TracChangeset for help on using the changeset viewer.