Changeset 2804 for branches


Ignore:
Timestamp:
Aug 31, 2006, 2:31:27 AM (19 years ago)
Author:
bird
Message:

Exception handlers. libc07 will fail initterm if an exception occurs during module regstration, libc06x will leave that to the other exception handlers.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/libc-0.6/src/emx/src/lib/sys/libcfork.c

    r2803 r2804  
    4242#include <string.h>
    4343#include <errno.h>
     44#include <setjmp.h>
    4445#include <emx/syscalls.h>
    4546#include <386/builtin.h>
     
    9192    volatile int                fDoneCompletion;
    9293} __LIBC_FORKXCPTREGREC, *__LIBC_PFORKXCPTREGREC;
     94
     95/**
     96 * Exception registration record used for the module registration
     97 * and deregistration APIs.
     98 */
     99typedef struct __LIBC_FORKXCPTREGREC2
     100{
     101    /** The OS/2 exception record. */
     102    EXCEPTIONREGISTRATIONRECORD Core;
     103    /** Our jump buffer. */
     104    jmp_buf                     JmpBuf;
     105} __LIBC_FORKXCPTREGREC2, *__LIBC_PFORKXCPTREGREC2;
     106
     107
    93108
    94109/**
     
    235250                                                    PCONTEXTRECORD               pCtx,
    236251                                                    PVOID                        pvWhatEver);
     252static ULONG _System        forkBthExceptionHandlerRegDereg(PEXCEPTIONREPORTRECORD       pXcptRepRec,
     253                                                            PEXCEPTIONREGISTRATIONRECORD pXcptRegRec,
     254                                                            PCONTEXTRECORD               pCtx,
     255                                                            PVOID                        pvWhatEver);
     256
    237257
    238258/*******************************************************************************
     
    336356    forkLogModuleByAddr(pModule->pvDataSegBase);
    337357#endif
    338     int                 rc;
    339     __LIBC_PSPMPROCESS  pProcess;
    340     __LIBC_PFORKHANDLE  pForkHandle;
    341     PTIB                pTib;
    342     PPIB                pPib;
    343     EXCEPTIONREGISTRATIONRECORD XcptRegRec;
     358    int                     rc;
     359    __LIBC_PSPMPROCESS      pProcess;
     360    __LIBC_PFORKHANDLE      pForkHandle;
     361    PTIB                    pTib;
     362    PPIB                    pPib;
     363    __LIBC_FORKXCPTREGREC2 XcptRegRec;
    344364
    345365    /*
     
    347367     */
    348368    DosGetInfoBlocks(&pTib, &pPib);
    349     XcptRegRec.ExceptionHandler = forkChlExceptionHandler;
    350     XcptRegRec.prev_structure = pTib->tib_pexchain;
    351     pTib->tib_pexchain = &XcptRegRec;
     369    XcptRegRec.Core.ExceptionHandler = forkBthExceptionHandlerRegDereg;
     370    XcptRegRec.Core.prev_structure = pTib->tib_pexchain;
     371    if (!setjmp(XcptRegRec.JmpBuf))
     372    {
     373        pTib->tib_pexchain = &XcptRegRec;
    352374
    353375#ifdef TIMEBOMB
    354     __libc_Timebomb();
     376        __libc_Timebomb();
    355377#endif
    356378
    357     /*
    358      * Find the SPM process.
    359      */
    360     pProcess = __libc_spmSelf();
    361     if (!pProcess)
    362     {
    363         static char szMsg[] = "LIBC Error: Couldn't register process in shared memory!\r\n";
    364         ULONG       ul;
    365         LIBC_ASSERTM_FAILED("couldn't register process!\n");
    366 
    367         DosWrite(2, szMsg, sizeof(szMsg), &ul);
    368         while (fExecutable)
    369         {
    370             LIBCLOG_MSG("Calling DosExit(EXIT_PROCESS, 0xffff)...\n");
    371             DosExit(EXIT_PROCESS, /*fixme*/0xffff);
    372         }
    373         pTib->tib_pexchain = XcptRegRec.prev_structure;
    374         LIBCLOG_RETURN_INT(-1);
    375     }
    376 
    377     /*
    378      * Register the module.
    379      * (We're hoping for OS/2 to indirectly serialize this... not properly verified yet.)
    380      */
    381     if (pModule->fFlags & __LIBC_FORKMODULE_FLAGS_DEREGISTERED)
    382         LIBCLOG_MSG("__LIBC_FORKMODULE_FLAGS_DEREGISTERED!\n");
    383     pModule->fFlags &= ~__LIBC_FORKMODULE_FLAGS_DEREGISTERED;
    384     pModule->pNext = NULL;
    385     if (pProcess->pvModuleHead)
    386         *(__LIBC_PFORKMODULE*)pProcess->ppvModuleTail = pModule;
    387     else
    388         pProcess->pvModuleHead = pModule;
    389     pProcess->ppvModuleTail = (void **)&pModule->pNext;
     379        /*
     380         * Find the SPM process.
     381         */
     382        pProcess = __libc_spmSelf();
     383        if (!pProcess)
     384        {
     385            static char szMsg[] = "LIBC Error: Couldn't register process in shared memory!\r\n";
     386            ULONG       ul;
     387            LIBC_ASSERTM_FAILED("couldn't register process!\n");
     388
     389            DosWrite(2, szMsg, sizeof(szMsg), &ul);
     390            while (fExecutable)
     391            {
     392                LIBCLOG_MSG("Calling DosExit(EXIT_PROCESS, 0xffff)...\n");
     393                DosExit(EXIT_PROCESS, /*fixme*/0xffff);
     394            }
     395            pTib->tib_pexchain = XcptRegRec.Core.prev_structure;
     396            LIBCLOG_RETURN_INT(-1);
     397        }
     398
     399        /*
     400         * Register the module.
     401         * (We're hoping for OS/2 to indirectly serialize this... not properly verified yet.)
     402         */
     403        if (pModule->fFlags & __LIBC_FORKMODULE_FLAGS_DEREGISTERED)
     404            LIBCLOG_MSG("__LIBC_FORKMODULE_FLAGS_DEREGISTERED!\n");
     405        pModule->fFlags &= ~__LIBC_FORKMODULE_FLAGS_DEREGISTERED;
     406        pModule->pNext = NULL;
     407        if (pProcess->pvModuleHead)
     408            *(__LIBC_PFORKMODULE*)pProcess->ppvModuleTail = pModule;
     409        else
     410            pProcess->pvModuleHead = pModule;
     411        pProcess->ppvModuleTail = (void **)&pModule->pNext;
    390412
    391413
    392414#if 0
    393     /*
    394      * Debug checks.
    395      */
    396     static char sz[] = "forking\0forking\0";
    397     PPIB pPib;
    398     PTIB pTib;
    399     DosGetInfoBlocks(&pTib, &pPib);
    400     if (!memcmp(pPib->pib_pchcmd, sz, sizeof(sz)))
    401     {
    402         LIBC_ASSERTM(pProcess->pvForkHandle, "fork arguments, no fork handle!!! process %p\n", pProcess);
     415        /*
     416         * Debug checks.
     417         */
     418        static char sz[] = "forking\0forking\0";
     419        PPIB pPib;
     420        PTIB pTib;
     421        DosGetInfoBlocks(&pTib, &pPib);
     422        if (!memcmp(pPib->pib_pchcmd, sz, sizeof(sz)))
     423        {
     424            LIBC_ASSERTM(pProcess->pvForkHandle, "fork arguments, no fork handle!!! process %p\n", pProcess);
     425            if (!pProcess->pvForkHandle)
     426                __libc_SpmCheck(0, 1);
     427        }
     428        else
     429        {
     430            LIBC_ASSERTM(!pProcess->pvForkHandle, "no fork arguments, fork handle!!! process %p handle %p\n", pProcess, pProcess->pvForkHandle);
     431            if (pProcess->pvForkHandle)
     432                __libc_SpmCheck(0, 1);
     433        }
     434#endif
     435
     436        /*
     437         * Are we forking?
     438         */
     439#ifdef TIMEBOMB
     440        forkTimebomb();
     441#endif
    403442        if (!pProcess->pvForkHandle)
    404             __libc_SpmCheck(0, 1);
    405     }
    406     else
    407     {
    408         LIBC_ASSERTM(!pProcess->pvForkHandle, "no fork arguments, fork handle!!! process %p handle %p\n", pProcess, pProcess->pvForkHandle);
    409         if (pProcess->pvForkHandle)
    410             __libc_SpmCheck(0, 1);
    411     }
    412 #endif
    413 
    414     /*
    415      * Are we forking?
    416      */
    417 #ifdef TIMEBOMB
    418     forkTimebomb();
    419 #endif
    420     if (!pProcess->pvForkHandle)
    421     {
    422         pTib->tib_pexchain = XcptRegRec.prev_structure;
    423         LIBCLOG_RETURN_INT(0);
    424     }
    425     /* we are! */
    426 
    427     /*
    428      * Open the fork handle.
    429      */
    430     pForkHandle = forkChlOpenHandle(pProcess->pvForkHandle);
    431     if (!pForkHandle)
    432     {
    433         while (fExecutable)
    434         {
    435             LIBCLOG_MSG("Calling DosExit(EXIT_PROCESS, 0xffff)...\n");
    436             DosExit(EXIT_PROCESS, /*fixme*/0xffff);
    437         }
    438         pTib->tib_pexchain = XcptRegRec.prev_structure;
    439         LIBCLOG_RETURN_INT(-1);
    440     }
    441     g_pForkHandle = pForkHandle;
    442 
    443     /*
    444      * Let pfnDoFork() process the module.
    445      */
    446     rc = pForkHandle->pfnDoFork(pForkHandle, pModule, fExecutable);
    447     if (rc < 0)
    448     {
    449         while (fExecutable)
    450         {
    451             LIBCLOG_MSG("Calling DosExit(EXIT_PROCESS, 0xffff)...\n");
    452             DosExit(EXIT_PROCESS, /*fixme*/0xffff);
    453         }
    454         pTib->tib_pexchain = XcptRegRec.prev_structure;
    455         LIBCLOG_RETURN_INT(-1);
    456     }
    457 
    458     /*
    459      * Done.
    460      */
    461     LIBC_ASSERT(!fExecutable);
    462     pTib->tib_pexchain = XcptRegRec.prev_structure;
    463     LIBCLOG_RETURN_INT(1);
     443        {
     444            pTib->tib_pexchain = XcptRegRec.Core.prev_structure;
     445            LIBCLOG_RETURN_INT(0);
     446        }
     447        /* we are! */
     448
     449        /*
     450         * Open the fork handle.
     451         */
     452        pForkHandle = forkChlOpenHandle(pProcess->pvForkHandle);
     453        if (!pForkHandle)
     454        {
     455            while (fExecutable)
     456            {
     457                LIBCLOG_MSG("Calling DosExit(EXIT_PROCESS, 0xffff)...\n");
     458                DosExit(EXIT_PROCESS, /*fixme*/0xffff);
     459            }
     460            pTib->tib_pexchain = XcptRegRec.Core.prev_structure;
     461            LIBCLOG_RETURN_INT(-1);
     462        }
     463        g_pForkHandle = pForkHandle;
     464
     465        /*
     466         * Let pfnDoFork() process the module.
     467         */
     468        XcptRegRec.Core.ExceptionHandler = forkChlExceptionHandler;
     469        rc = pForkHandle->pfnDoFork(pForkHandle, pModule, fExecutable);
     470        if (rc < 0)
     471        {
     472            while (fExecutable)
     473            {
     474                LIBCLOG_MSG("Calling DosExit(EXIT_PROCESS, 0xffff)...\n");
     475                DosExit(EXIT_PROCESS, /*fixme*/0xffff);
     476            }
     477            pTib->tib_pexchain = XcptRegRec.Core.prev_structure;
     478            LIBCLOG_RETURN_INT(-1);
     479        }
     480
     481        /*
     482         * Done.
     483         */
     484        LIBC_ASSERT(!fExecutable);
     485        pTib->tib_pexchain = XcptRegRec.Core.prev_structure;
     486        LIBCLOG_RETURN_INT(1);
     487    }
     488
     489    /* Exception! */
     490    LIBCLOG_RETURN_INT(-1);
    464491}
    465492
     
    482509    forkLogModuleByAddr(pModule->pvDataSegBase);
    483510#endif
    484 
    485     /*
    486      * Don't deregister modules which has already been deregistered.
    487      * Don't deregister if we're in shutting down the process (waste of time and
    488      * SPM might already be shut down).
    489      */
    490     if (pModule->fFlags & __LIBC_FORKMODULE_FLAGS_DEREGISTERED)
    491         LIBCLOG_RETURN_MSG_VOID( "ret void (__LIBC_FORKMODULE_FLAGS_DEREGISTERD)\n");
    492     if (!__libc_GpFIBLIS)
    493         LIBCLOG_RETURN_MSG_VOID( "ret void (__libc_GpFIBLIS)\n");
    494     if (fibIsInExit())
    495         LIBCLOG_RETURN_MSG_VOID( "ret void (fibIsInExit)\n");
    496 
    497     /*
    498      * Find the SPM process.
    499      */
    500     __LIBC_PSPMPROCESS pProcess = __libc_spmSelf();
    501     if (!pProcess)
    502     {
    503         LIBC_ASSERTM_FAILED("can't find the process! weird!\n");
     511    PTIB                    pTib;
     512    PPIB                    pPib;
     513    __LIBC_FORKXCPTREGREC2  XcptRegRec;
     514
     515    /*
     516     * Install an exceptionhandler.
     517     */
     518    DosGetInfoBlocks(&pTib, &pPib);
     519    XcptRegRec.Core.ExceptionHandler = forkBthExceptionHandlerRegDereg;
     520    XcptRegRec.Core.prev_structure = pTib->tib_pexchain;
     521    if (!setjmp(XcptRegRec.JmpBuf))
     522    {
     523        pTib->tib_pexchain = &XcptRegRec;
     524
     525        /*
     526         * Don't deregister modules which has already been deregistered.
     527         * Don't deregister if we're in shutting down the process (waste of time and
     528         * SPM might already be shut down).
     529         */
     530        if (pModule->fFlags & __LIBC_FORKMODULE_FLAGS_DEREGISTERED)
     531        {
     532            pTib->tib_pexchain = XcptRegRec.Core.prev_structure;
     533            LIBCLOG_RETURN_MSG_VOID( "ret void (__LIBC_FORKMODULE_FLAGS_DEREGISTERD)\n");
     534        }
     535        if (!__libc_GpFIBLIS)
     536        {
     537            pTib->tib_pexchain = XcptRegRec.Core.prev_structure;
     538            LIBCLOG_RETURN_MSG_VOID( "ret void (__libc_GpFIBLIS)\n");
     539        }
     540        if (fibIsInExit())
     541        {
     542            pTib->tib_pexchain = XcptRegRec.Core.prev_structure;
     543            LIBCLOG_RETURN_MSG_VOID( "ret void (fibIsInExit)\n");
     544        }
     545
     546        /*
     547         * Find the SPM process.
     548         */
     549        __LIBC_PSPMPROCESS pProcess = __libc_spmSelf();
     550        if (!pProcess)
     551        {
     552            pTib->tib_pexchain = XcptRegRec.Core.prev_structure;
     553            LIBC_ASSERTM_FAILED("can't find the process! weird!\n");
     554            LIBCLOG_RETURN_VOID();
     555        }
     556
     557        /*
     558         * Deregister the module.
     559         * (We're hoping for OS/2 to indirectly serialize this... not properly verified yet.)
     560         */
     561        if ((__LIBC_PFORKMODULE)pProcess->pvModuleHead == pModule)
     562        {
     563            pProcess->pvModuleHead = pModule->pNext;
     564            if (!pModule->pNext)
     565                pProcess->ppvModuleTail = &pProcess->pvModuleHead;
     566        }
     567        else
     568        {
     569            __LIBC_PFORKMODULE pPrev = (__LIBC_PFORKMODULE)pProcess->pvModuleHead;
     570            while (pPrev && pPrev->pNext != pModule)
     571                pPrev = pPrev->pNext;
     572            if (!pPrev)
     573            {
     574                pTib->tib_pexchain = XcptRegRec.Core.prev_structure;
     575                LIBC_ASSERTM_FAILED("can't find the module! weird!\n");
     576                LIBCLOG_RETURN_VOID();
     577            }
     578
     579            pPrev->pNext = pModule->pNext;
     580            if (!pModule->pNext)
     581                pProcess->ppvModuleTail = (void **)&pPrev->pNext;
     582        }
     583
     584        pModule->pNext = NULL;
     585        pModule->fFlags |= __LIBC_FORKMODULE_FLAGS_DEREGISTERED;
     586
     587        pTib->tib_pexchain = XcptRegRec.Core.prev_structure;
    504588        LIBCLOG_RETURN_VOID();
    505589    }
    506590
    507     /*
    508      * Deregister the module.
    509      * (We're hoping for OS/2 to indirectly serialize this... not properly verified yet.)
    510      */
    511     if ((__LIBC_PFORKMODULE)pProcess->pvModuleHead == pModule)
    512     {
    513         pProcess->pvModuleHead = pModule->pNext;
    514         if (!pModule->pNext)
    515             pProcess->ppvModuleTail = &pProcess->pvModuleHead;
    516     }
    517     else
    518     {
    519         __LIBC_PFORKMODULE pPrev = (__LIBC_PFORKMODULE)pProcess->pvModuleHead;
    520         while (pPrev && pPrev->pNext != pModule)
    521             pPrev = pPrev->pNext;
    522         if (!pPrev)
    523         {
    524             LIBC_ASSERTM_FAILED("can't find the module! weird!\n");
    525             LIBCLOG_RETURN_VOID();
    526         }
    527 
    528         pPrev->pNext = pModule->pNext;
    529         if (!pModule->pNext)
    530             pProcess->ppvModuleTail = (void **)&pPrev->pNext;
    531     }
    532 
    533     pModule->pNext = NULL;
    534     pModule->fFlags |= __LIBC_FORKMODULE_FLAGS_DEREGISTERED;
    535 
     591    /* Exception! */
    536592    LIBCLOG_RETURN_VOID();
    537593}
     
    728784 * @param   pvForkRet       Return address for the child.
    729785 * @param   pvStackRet      ESP for the child when returning from fork.
    730  * @param   pXctpRegRec     Pointer to the exception registration record (fDoneCompletion).
     786 * @param   pXcptRegRec     Pointer to the exception registration record (fDoneCompletion).
    731787 */
    732788static int forkParDo(void *pvForkRet, void *pvStackRet, __LIBC_PFORKXCPTREGREC pXcptRegRec)
     
    33493405}
    33503406
     3407
     3408/**
     3409 * Exception handler for the module registration/deregistration.
     3410 *
     3411 * @returns XCPT_CONTINUE_SEARCH or XCPT_CONTINUE_EXECUTION.
     3412 * @param   pXcptRepRec     Report record.
     3413 * @param   pXcptRegRec     Registration record.
     3414 * @param   pCtx            Context record.
     3415 * @param   pvWhatEver      Not quite sure what this is...
     3416 */
     3417static ULONG _System forkBthExceptionHandlerRegDereg(PEXCEPTIONREPORTRECORD       pXcptRepRec,
     3418                                                     PEXCEPTIONREGISTRATIONRECORD pXcptRegRec,
     3419                                                     PCONTEXTRECORD               pCtx,
     3420                                                     PVOID                        pvWhatEver)
     3421{
     3422    __asm__ ("cld");                    /* usual paranoia.  */
     3423
     3424    if (pXcptRepRec->fHandlerFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
     3425        return XCPT_CONTINUE_SEARCH;
     3426
     3427    LIBCLOG_MSG2("forkBthExceptionHandlerRegDereg: ExceptionNum=%#lx ExceptionAddress=%p eip=%#lx ExceptionInfo={%#08lx,%#08lx,%#08lx,%#08lx} fHandlerFlags=%#lx\n",
     3428                 pXcptRepRec->ExceptionNum, pXcptRepRec->ExceptionAddress, pCtx->ctx_RegEip,
     3429                 pXcptRepRec->ExceptionInfo[0], pXcptRepRec->ExceptionInfo[1],
     3430                 pXcptRepRec->ExceptionInfo[2], pXcptRepRec->ExceptionInfo[3],
     3431                 pXcptRepRec->fHandlerFlags);
     3432
     3433    switch (pXcptRepRec->ExceptionNum)
     3434    {
     3435        /*
     3436         * It's ok to get signaled, terminated or similar.
     3437         */
     3438        case XCPT_SIGNAL:
     3439        case XCPT_ASYNC_PROCESS_TERMINATE:
     3440        case XCPT_PROCESS_TERMINATE:
     3441        default:
     3442            return XCPT_CONTINUE_SEARCH;
     3443
     3444        /*
     3445         * Most otherthings should be considered fatal and
     3446         * cause module initialization to fail.
     3447         */
     3448        case XCPT_ACCESS_VIOLATION:
     3449        case XCPT_DATATYPE_MISALIGNMENT:
     3450        case XCPT_INTEGER_OVERFLOW:
     3451        case XCPT_INTEGER_DIVIDE_BY_ZERO:
     3452        case XCPT_FLOAT_DIVIDE_BY_ZERO:
     3453        case XCPT_FLOAT_OVERFLOW:
     3454        case XCPT_FLOAT_UNDERFLOW:
     3455        case XCPT_FLOAT_DENORMAL_OPERAND:
     3456        case XCPT_FLOAT_INEXACT_RESULT:
     3457        case XCPT_FLOAT_INVALID_OPERATION:
     3458        case XCPT_FLOAT_STACK_CHECK:
     3459        case XCPT_ARRAY_BOUNDS_EXCEEDED:
     3460        case XCPT_ILLEGAL_INSTRUCTION:
     3461        case XCPT_INVALID_LOCK_SEQUENCE:
     3462        case XCPT_PRIVILEGED_INSTRUCTION:
     3463        case XCPT_SINGLE_STEP:
     3464        case XCPT_BREAKPOINT:
     3465        {
     3466            __LIBC_PFORKXCPTREGREC2 pRegRec = (__LIBC_PFORKXCPTREGREC2)pXcptRegRec;
     3467            PPIB                    pPib;
     3468            PTIB                    pTib;
     3469
     3470            DosGetInfoBlocks(&pTib, &pPib);
     3471            pTib->tib_pexchain = pRegRec->Core.prev_structure;
     3472
     3473#if 0 /* can't do this in libc06x because of compatability issues */
     3474            longjmp(pRegRec->JmpBuf, -1);
     3475#endif
     3476            return XCPT_CONTINUE_SEARCH;
     3477        }
     3478    }
     3479
     3480}
     3481
Note: See TracChangeset for help on using the changeset viewer.