Ignore:
Timestamp:
Jun 18, 2009, 11:53:26 AM (16 years ago)
Author:
ydario
Message:

Kernel32 updates.

File:
1 edited

Legend:

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

    r10409 r21302  
    5252#define INCL_MISC
    5353#define INCL_BASE
     54#define INCL_WIN
    5455#define INCL_WINBUTTONS
    5556#include <os2wrap.h>                     //Odin32 OS/2 api wrappers
     
    5960#include <time.h>
    6061#include <string.h>
     62#include <pmscan.h>
    6163#include "exceptions.h"
    6264#include "exceptutil.h"
     
    6668#include <win32api.h>
    6769#include "oslibexcept.h"
     70#include "oslibmem.h"
    6871#include "exceptstackdump.h"
     72#include "hmthread.h"
    6973
    7074#include "WinImageBase.h"
     
    8185#define DBG_LOCALLOG    DBG_exceptions
    8286#include "dbglocal.h"
     87
     88#include <_ras.h>
    8389
    8490#ifdef WITH_KLIB
     
    672678    static BOOL fEntry = FALSE;
    673679
    674     if(fEntry == FALSE) {
     680    if(!fExitProcess && fEntry == FALSE) {
    675681        fEntry = TRUE;
    676682        ExitProcess(666);
     
    702708                             PSZ                          szTrapDump)
    703709{
     710// @@VP20040507: This function uses a static buffer szTrapDump, therefore
     711//               any local buffers also can be made static to save
     712//               stack space and possibly avoid out of stack exception.
     713    if(pERepRec->ExceptionNum == XCPT_GUARD_PAGE_VIOLATION)   
     714    {
     715        strcpy(szTrapDump, "Guard Page Violation");
     716        return;
     717    }
     718   
    704719    PSZ    pszExceptionName = "<unknown>";        /* points to name/type excpt */
    705720    APIRET rc               = XCPT_CONTINUE_SEARCH;        /* excpt-dep.  code */
     
    711726    ULONG  ulModule;                                          /* module number */
    712727    ULONG  ulObject;                        /* object number within the module */
    713     CHAR   szModule[260];                        /* buffer for the module name */
     728static    CHAR   szModule[260];                        /* buffer for the module name */
    714729    ULONG  ulOffset;             /* offset within the object within the module */
    715     char   szLineException[128];
    716     char   szLineExceptionType[128];
     730static    char   szLineException[128];
     731static    char   szLineExceptionType[128];
    717732
    718733    szLineException[0]  = 0;                                              /* initialize */
     
    944959    if(rc == NO_ERROR && ulObject != -1)
    945960    {
    946         sprintf(szLineException, "<%.*s> (#%u) obj #%u:%08x\n", 64, szModule, ulModule, ulObject, ulOffset);
     961        sprintf(szLineException, "<%.*s> (#%u) obj #%u:%08x", 64, szModule, ulModule, ulObject, ulOffset);
     962#ifdef RAS
     963        static char szSYMInfo[260];
     964        static char Name[260];
     965       
     966        DosQueryModuleName(ulModule, sizeof(Name), Name);
     967
     968        int namelen = strlen(Name);
     969        if(namelen > 3)
     970        {
     971                strcpy(Name + namelen - 3, "SYM");
     972                dbgGetSYMInfo(Name, ulObject, ulOffset, szSYMInfo, sizeof (szSYMInfo));
     973                strcat(szLineException, " ");
     974                strcat(szLineException, szSYMInfo);
     975        }
     976#else
     977        strcat(szLineException, "\n");
     978#endif
    947979        strcat(szTrapDump, szLineException);
    948980    }
     
    10441076                             PVOID                        p)
    10451077{
     1078    sprintfException(pERepRec, pERegRec, pCtxRec, p, szTrapDump);
     1079#ifdef RAS
     1080    RasLog (szTrapDump);
     1081#endif
    10461082    /* now dump the information to the logfile */
    10471083    dprintf(("\n%s", szTrapDump));
     
    10651101//*****************************************************************************
    10661102//*****************************************************************************
    1067 static void logException()
     1103static void logException(PEXCEPTIONREPORTRECORD pERepRec, PEXCEPTIONREGISTRATIONRECORD pERegRec, PCONTEXTRECORD pCtxRec, PVOID p)
    10681104{
    10691105    APIRET rc;
     
    11101146            DosWrite(hFile, lpszTime, strlen(lpszTime), &ulBytesWritten);
    11111147        }
     1148        sprintfException(pERepRec, pERegRec, pCtxRec, p, szTrapDump);
     1149#ifdef RAS
     1150        RasLog (szTrapDump);
     1151#endif
    11121152        DosWrite(hFile, szTrapDump, strlen(szTrapDump), &ulBytesWritten);
    11131153        DosClose(hFile);
     
    11471187    int prevlock = LogException(ENTER_EXCEPTION);
    11481188
    1149     //Print exception name & exception type
    1150     //Not for a guard page exception as sprintfException uses a lot of stack
    1151     //and can trigger nested guard page exceptions (crash)
    1152     if(pERepRec->ExceptionNum != XCPT_GUARD_PAGE_VIOLATION) {
    1153         sprintfException(pERepRec, pERegRec, pCtxRec, p, szTrapDump);
    1154     }
     1189// @@VP20040507: no need to sprintf every exception
     1190//    //Print exception name & exception type
     1191//    //Not for a guard page exception as sprintfException uses a lot of stack
     1192//    //and can trigger nested guard page exceptions (crash)
     1193//    if(pERepRec->ExceptionNum != XCPT_GUARD_PAGE_VIOLATION) {
     1194//        sprintfException(pERepRec, pERegRec, pCtxRec, p, szTrapDump);
     1195//    }
    11551196
    11561197    /* Access violation at a known location */
     
    12961337    }
    12971338#endif
    1298 
     1339    goto CrashAndBurn;
     1340
     1341    case XCPT_INVALID_LOCK_SEQUENCE:
     1342    {
     1343        TEB *teb = GetThreadTEB();
     1344        USHORT *eip = (USHORT *)pCtxRec->ctx_RegEip;
     1345
     1346        if(teb && eip && *eip == SETTHREADCONTEXT_INVALID_LOCKOPCODE)
     1347        {
     1348            //Is this a pending SetThreadContext exception?
     1349            //(see detailed description in the HMDeviceThreadClass::SetThreadContext method)
     1350            if(teb->o.odin.context.ContextFlags)
     1351            {
     1352                dprintfException(pERepRec, pERegRec, pCtxRec, p);
     1353
     1354                //NOTE: This will not work properly in case multiple threads execute this code
     1355                dprintf(("Changing thread registers (SetThreadContext)!!"));
     1356
     1357                if(teb->o.odin.context.ContextFlags & WINCONTEXT_CONTROL) {
     1358                    pCtxRec->ctx_RegEbp = teb->o.odin.context.Ebp;
     1359                    pCtxRec->ctx_RegEip = teb->o.odin.context.Eip;
     1360////                    pCtxRec->ctx_SegCs  = teb->o.odin.context.SegCs;
     1361                    pCtxRec->ctx_EFlags = teb->o.odin.context.EFlags;
     1362                    pCtxRec->ctx_RegEsp = teb->o.odin.context.Esp;
     1363////                    pCtxRec->ctx_SegSs  = teb->o.odin.context.SegSs;
     1364                }
     1365                if(teb->o.odin.context.ContextFlags & WINCONTEXT_INTEGER) {
     1366                    pCtxRec->ctx_RegEdi = teb->o.odin.context.Edi;
     1367                    pCtxRec->ctx_RegEsi = teb->o.odin.context.Esi;
     1368                    pCtxRec->ctx_RegEbx = teb->o.odin.context.Ebx;
     1369                    pCtxRec->ctx_RegEdx = teb->o.odin.context.Edx;
     1370                    pCtxRec->ctx_RegEcx = teb->o.odin.context.Ecx;
     1371                    pCtxRec->ctx_RegEax = teb->o.odin.context.Eax;
     1372                }
     1373                if(teb->o.odin.context.ContextFlags & WINCONTEXT_SEGMENTS) {
     1374                    pCtxRec->ctx_SegGs  = teb->o.odin.context.SegGs;
     1375////                    pCtxRec->ctx_SegFs  = teb->o.odin.context.SegFs;
     1376                    pCtxRec->ctx_SegEs  = teb->o.odin.context.SegEs;
     1377                    pCtxRec->ctx_SegDs  = teb->o.odin.context.SegDs;
     1378                }
     1379                if(teb->o.odin.context.ContextFlags & WINCONTEXT_FLOATING_POINT) {
     1380                    //TODO: First 7 dwords the same?
     1381                    memcpy(pCtxRec->ctx_env, &teb->o.odin.context.FloatSave, sizeof(pCtxRec->ctx_env));
     1382                    memcpy(pCtxRec->ctx_stack, &teb->o.odin.context.FloatSave.RegisterArea, sizeof(pCtxRec->ctx_stack));
     1383                }
     1384                USHORT *lpAlias = (USHORT *)((char *)teb->o.odin.lpAlias + teb->o.odin.dwAliasOffset);
     1385                *lpAlias = teb->o.odin.savedopcode;
     1386
     1387                //Clear SetThreadContext markers
     1388                teb->o.odin.context.ContextFlags = 0;
     1389
     1390                OSLibDosFreeMem(teb->o.odin.lpAlias);
     1391
     1392                teb->o.odin.lpAlias              = NULL;
     1393                teb->o.odin.dwAliasOffset        = 0;
     1394
     1395                //restore the original priority (we boosted it to ensure this thread was scheduled first)
     1396                SetThreadPriority(teb->o.odin.hThread, GetThreadPriority(teb->o.odin.hThread));
     1397                goto continueexecution;
     1398            }
     1399            else DebugInt3(); //oh, oh!!!!!
     1400
     1401        }
     1402        //no break;
     1403    }
     1404
     1405    case XCPT_PRIVILEGED_INSTRUCTION:
     1406    case XCPT_ILLEGAL_INSTRUCTION:
    12991407    case XCPT_BREAKPOINT:
    13001408    case XCPT_ARRAY_BOUNDS_EXCEEDED:
    13011409    case XCPT_DATATYPE_MISALIGNMENT:
    1302     case XCPT_ILLEGAL_INSTRUCTION:
    1303     case XCPT_PRIVILEGED_INSTRUCTION:
    1304     case XCPT_INVALID_LOCK_SEQUENCE:
    13051410    case XCPT_INTEGER_DIVIDE_BY_ZERO:
    13061411    case XCPT_INTEGER_OVERFLOW:
    13071412    case XCPT_SINGLE_STEP:
    1308     case XCPT_UNABLE_TO_GROW_STACK:
    13091413    case XCPT_IN_PAGE_ERROR:
    13101414CrashAndBurn:
     
    13161420                goto continuesearch;
    13171421
    1318 #ifdef DEBUG
     1422#if defined(DEBUG) || defined(RAS)
    13191423        dprintfException(pERepRec, pERegRec, pCtxRec, p);
     1424
    13201425        if(!fExitProcess && (pCtxRec->ContextFlags & CONTEXT_CONTROL)) {
    13211426                dbgPrintStack(pERepRec, pERegRec, pCtxRec, p);
     
    13371442
    13381443                rc = DosGetInfoBlocks (&pTIB, &pPIB);
    1339                 if(rc == NO_ERROR && pTIB->tib_ptib2->tib2_ultid != 1)
     1444                if(rc == NO_ERROR)
    13401445                {
    13411446                    dprintf(("KERNEL32: OS2ExceptionHandler: Continue and kill thread"));
    13421447
    1343                     pCtxRec->ctx_RegEip = (ULONG)KillWin32Thread;
     1448                    pCtxRec->ctx_RegEip = (pTIB->tib_ptib2->tib2_ultid != 1) ? (ULONG)KillWin32Thread : (ULONG)KillWin32Process;
    13441449                    pCtxRec->ctx_RegEsp = pCtxRec->ctx_RegEsp + 0x10;
    13451450                    pCtxRec->ctx_RegEax = pERepRec->ExceptionNum;
     
    13521457
    13531458        //Log fatal exception here
    1354         logException();
     1459        logException(pERepRec, pERegRec, pCtxRec, p);
    13551460
    13561461        dprintf(("KERNEL32: OS2ExceptionHandler: Continue and kill\n"));
     
    13621467        goto continueexecution;
    13631468
    1364     //@@@PH: growing thread stacks might need special treatment
    13651469    case XCPT_GUARD_PAGE_VIOLATION:
    13661470    {
     
    13691473        //inside fprintf
    13701474        //NOTE:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    1371 
     1475        TEB *teb = GetThreadTEB();
     1476        DWORD stacktop, stackbottom;
     1477
     1478        if(teb == NULL) {
     1479            goto continueGuardException;
     1480        }
     1481
     1482        stacktop    = (DWORD)teb->stack_top;
     1483        stackbottom = (DWORD)teb->stack_low;
     1484
     1485        stackbottom = stackbottom & ~0xFFF;   //round down to page boundary
     1486        stacktop    = stacktop & ~0xFFF;
     1487
     1488        //Make sure we detect a stack overflow condition before the system does
     1489        if(!fIsOS2Image &&
     1490            pERepRec->ExceptionInfo[1]  >= stackbottom &&
     1491            pERepRec->ExceptionInfo[1]  <  stacktop
     1492           )
     1493        {//this is a guard page exception for the thread stack
     1494            APIRET rc;
     1495            ULONG ulAddress, cbSize, ulMemFlags;
     1496 
     1497            //round down to page boundary
     1498            ulAddress = pERepRec->ExceptionInfo[1] & ~0xFFF;
     1499
     1500#if 0
     1501            rc = DosQueryMem((PVOID)ulAddress, &cbSize, &ulMemFlags);
     1502            if(rc) {
     1503                dprintf(("ERROR: DosQueryMem old guard page failed with rc %d", rc));
     1504                goto continueGuardException;
     1505            }
     1506#endif
     1507
     1508            if(ulAddress == stackbottom + PAGE_SIZE)
     1509            {//we don't have any stack left, throw an XCPT_UNABLE_TO_GROW_STACK
     1510             //exception
     1511                if(!fExitProcess)  //Only for real win32 apps
     1512                {
     1513                    EXCEPTIONREPORTRECORD recoutofstack;
     1514
     1515                    recoutofstack               = *pERepRec;
     1516                    recoutofstack.ExceptionNum  = XCPT_UNABLE_TO_GROW_STACK;
     1517                    recoutofstack.fHandlerFlags = 0;
     1518                    recoutofstack.NestedExceptionReportRecord = NULL;
     1519                    recoutofstack.cParameters   = 0;
     1520
     1521                    if(OSLibDispatchException(&recoutofstack, pERegRec, pCtxRec, p) == TRUE)
     1522                    {
     1523                        goto continueexecution;
     1524                    }
     1525                }
     1526            }
     1527        }
     1528        else
     1529        {//check for memory map guard page exception
    13721530        Win32MemMap *map;
    13731531        BOOL  fWriteAccess = FALSE, ret;
     
    13871545
    13881546        map = Win32MemMapView::findMapByView(pERepRec->ExceptionInfo[1], &offset, accessflag);
    1389         if(map == NULL) {
    1390             goto continueGuardException;
    1391         }
     1547            if(map) {
    13921548        ret = map->commitGuardPage(pERepRec->ExceptionInfo[1], offset, fWriteAccess);
    13931549        map->Release();
    13941550        if(ret == TRUE)
    13951551            goto continueexecution;
     1552            }           
     1553        }
    13961554
    13971555continueGuardException:
     1556        goto continuesearch;
     1557    }
     1558
     1559    case XCPT_UNABLE_TO_GROW_STACK:
     1560    {
     1561        //SvL: XCPT_UNABLE_TO_GROW_STACK is typically nested (failed guard page
     1562        //     exception), so don't ignore them
     1563        // We should no longer receive those!!
     1564// @@VP20040507: Isn't this a bit dangerous to call dprintfon such exception
     1565//#ifdef DEBUG
     1566//        dprintfException(pERepRec, pERegRec, pCtxRec, p);
     1567//#endif     
    13981568        goto continuesearch;
    13991569    }
     
    14081578     */
    14091579    case XCPT_SIGNAL:
     1580    {
     1581        //This is not a reliable way to distinguish between Ctrl-C & Ctrl-Break
     1582        BOOL breakPressed = WinGetKeyState(HWND_DESKTOP,VK_BREAK) & 0x8000;
     1583
    14101584        switch (pERepRec->ExceptionInfo[0])
    14111585        {
    14121586            case XCPT_SIGNAL_BREAK:
    1413                 if (InternalGenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0))
     1587                breakPressed = TRUE;
     1588                //no break
     1589
     1590            case XCPT_SIGNAL_INTR:
     1591                dprintfException(pERepRec, pERegRec, pCtxRec, p);
     1592                if (InternalGenerateConsoleCtrlEvent((breakPressed) ? CTRL_BREAK_EVENT : CTRL_C_EVENT, 0))
     1593                {
     1594                    DosAcknowledgeSignalException(pERepRec->ExceptionInfo[0]);
    14141595                    goto continueexecution;
    1415                 goto continuesearch;
    1416             case XCPT_SIGNAL_INTR:
    1417                 if (InternalGenerateConsoleCtrlEvent(CTRL_C_EVENT, 0))
    1418                     goto continueexecution;
     1596                }
    14191597                goto continuesearch;
    14201598
     
    14241602        }
    14251603        goto CrashAndBurn;
     1604    }
    14261605
    14271606    default: //non-continuable exceptions
     
    14971676  USHORT sel = RestoreOS2FS();
    14981677  PEXCEPTIONREGISTRATIONRECORD pExceptRec = (PEXCEPTIONREGISTRATIONRECORD)QueryExceptionChain();
    1499 
    1500   if(pExceptRec == (PEXCEPTIONREGISTRATIONRECORD)pExceptionRegRec) {
     1678  BOOL   fFound = FALSE;
     1679
     1680  while(pExceptRec != 0 && (ULONG)pExceptRec != -1)
     1681  {
     1682        if(pExceptRec == pExceptionRegRec)
     1683        {
     1684            fFound = TRUE;
     1685            break;
     1686        }
     1687        pExceptRec = pExceptRec->prev_structure;
     1688  }
     1689
     1690#ifdef DEBUG
     1691  pExceptRec = (PEXCEPTIONREGISTRATIONRECORD)QueryExceptionChain();
     1692
     1693  if(fFound && pExceptRec != (PEXCEPTIONREGISTRATIONRECORD)pExceptionRegRec)
     1694  {
     1695      dprintf(("ERROR: ODIN_UnsetExceptionHandler: INSIDE!!!: exc rec %p, head %p\n", pExceptionRegRec, pExceptRec));
     1696      PrintExceptionChain ();
     1697  }
     1698#endif
     1699  if(fFound) {
    15011700      OS2UnsetExceptionHandler(pExceptionRegRec);
    15021701  }
Note: See TracChangeset for help on using the changeset viewer.