Changeset 21302 for trunk/src/kernel32/exceptions.cpp
- Timestamp:
- Jun 18, 2009, 11:53:26 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/exceptions.cpp
r10409 r21302 52 52 #define INCL_MISC 53 53 #define INCL_BASE 54 #define INCL_WIN 54 55 #define INCL_WINBUTTONS 55 56 #include <os2wrap.h> //Odin32 OS/2 api wrappers … … 59 60 #include <time.h> 60 61 #include <string.h> 62 #include <pmscan.h> 61 63 #include "exceptions.h" 62 64 #include "exceptutil.h" … … 66 68 #include <win32api.h> 67 69 #include "oslibexcept.h" 70 #include "oslibmem.h" 68 71 #include "exceptstackdump.h" 72 #include "hmthread.h" 69 73 70 74 #include "WinImageBase.h" … … 81 85 #define DBG_LOCALLOG DBG_exceptions 82 86 #include "dbglocal.h" 87 88 #include <_ras.h> 83 89 84 90 #ifdef WITH_KLIB … … 672 678 static BOOL fEntry = FALSE; 673 679 674 if( fEntry == FALSE) {680 if(!fExitProcess && fEntry == FALSE) { 675 681 fEntry = TRUE; 676 682 ExitProcess(666); … … 702 708 PSZ szTrapDump) 703 709 { 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 704 719 PSZ pszExceptionName = "<unknown>"; /* points to name/type excpt */ 705 720 APIRET rc = XCPT_CONTINUE_SEARCH; /* excpt-dep. code */ … … 711 726 ULONG ulModule; /* module number */ 712 727 ULONG ulObject; /* object number within the module */ 713 CHAR szModule[260]; /* buffer for the module name */728 static CHAR szModule[260]; /* buffer for the module name */ 714 729 ULONG ulOffset; /* offset within the object within the module */ 715 char szLineException[128];716 char szLineExceptionType[128];730 static char szLineException[128]; 731 static char szLineExceptionType[128]; 717 732 718 733 szLineException[0] = 0; /* initialize */ … … 944 959 if(rc == NO_ERROR && ulObject != -1) 945 960 { 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 947 979 strcat(szTrapDump, szLineException); 948 980 } … … 1044 1076 PVOID p) 1045 1077 { 1078 sprintfException(pERepRec, pERegRec, pCtxRec, p, szTrapDump); 1079 #ifdef RAS 1080 RasLog (szTrapDump); 1081 #endif 1046 1082 /* now dump the information to the logfile */ 1047 1083 dprintf(("\n%s", szTrapDump)); … … 1065 1101 //***************************************************************************** 1066 1102 //***************************************************************************** 1067 static void logException( )1103 static void logException(PEXCEPTIONREPORTRECORD pERepRec, PEXCEPTIONREGISTRATIONRECORD pERegRec, PCONTEXTRECORD pCtxRec, PVOID p) 1068 1104 { 1069 1105 APIRET rc; … … 1110 1146 DosWrite(hFile, lpszTime, strlen(lpszTime), &ulBytesWritten); 1111 1147 } 1148 sprintfException(pERepRec, pERegRec, pCtxRec, p, szTrapDump); 1149 #ifdef RAS 1150 RasLog (szTrapDump); 1151 #endif 1112 1152 DosWrite(hFile, szTrapDump, strlen(szTrapDump), &ulBytesWritten); 1113 1153 DosClose(hFile); … … 1147 1187 int prevlock = LogException(ENTER_EXCEPTION); 1148 1188 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 // } 1155 1196 1156 1197 /* Access violation at a known location */ … … 1296 1337 } 1297 1338 #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: 1299 1407 case XCPT_BREAKPOINT: 1300 1408 case XCPT_ARRAY_BOUNDS_EXCEEDED: 1301 1409 case XCPT_DATATYPE_MISALIGNMENT: 1302 case XCPT_ILLEGAL_INSTRUCTION:1303 case XCPT_PRIVILEGED_INSTRUCTION:1304 case XCPT_INVALID_LOCK_SEQUENCE:1305 1410 case XCPT_INTEGER_DIVIDE_BY_ZERO: 1306 1411 case XCPT_INTEGER_OVERFLOW: 1307 1412 case XCPT_SINGLE_STEP: 1308 case XCPT_UNABLE_TO_GROW_STACK:1309 1413 case XCPT_IN_PAGE_ERROR: 1310 1414 CrashAndBurn: … … 1316 1420 goto continuesearch; 1317 1421 1318 #if def DEBUG1422 #if defined(DEBUG) || defined(RAS) 1319 1423 dprintfException(pERepRec, pERegRec, pCtxRec, p); 1424 1320 1425 if(!fExitProcess && (pCtxRec->ContextFlags & CONTEXT_CONTROL)) { 1321 1426 dbgPrintStack(pERepRec, pERegRec, pCtxRec, p); … … 1337 1442 1338 1443 rc = DosGetInfoBlocks (&pTIB, &pPIB); 1339 if(rc == NO_ERROR && pTIB->tib_ptib2->tib2_ultid != 1)1444 if(rc == NO_ERROR) 1340 1445 { 1341 1446 dprintf(("KERNEL32: OS2ExceptionHandler: Continue and kill thread")); 1342 1447 1343 pCtxRec->ctx_RegEip = ( ULONG)KillWin32Thread;1448 pCtxRec->ctx_RegEip = (pTIB->tib_ptib2->tib2_ultid != 1) ? (ULONG)KillWin32Thread : (ULONG)KillWin32Process; 1344 1449 pCtxRec->ctx_RegEsp = pCtxRec->ctx_RegEsp + 0x10; 1345 1450 pCtxRec->ctx_RegEax = pERepRec->ExceptionNum; … … 1352 1457 1353 1458 //Log fatal exception here 1354 logException( );1459 logException(pERepRec, pERegRec, pCtxRec, p); 1355 1460 1356 1461 dprintf(("KERNEL32: OS2ExceptionHandler: Continue and kill\n")); … … 1362 1467 goto continueexecution; 1363 1468 1364 //@@@PH: growing thread stacks might need special treatment1365 1469 case XCPT_GUARD_PAGE_VIOLATION: 1366 1470 { … … 1369 1473 //inside fprintf 1370 1474 //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 1372 1530 Win32MemMap *map; 1373 1531 BOOL fWriteAccess = FALSE, ret; … … 1387 1545 1388 1546 map = Win32MemMapView::findMapByView(pERepRec->ExceptionInfo[1], &offset, accessflag); 1389 if(map == NULL) { 1390 goto continueGuardException; 1391 } 1547 if(map) { 1392 1548 ret = map->commitGuardPage(pERepRec->ExceptionInfo[1], offset, fWriteAccess); 1393 1549 map->Release(); 1394 1550 if(ret == TRUE) 1395 1551 goto continueexecution; 1552 } 1553 } 1396 1554 1397 1555 continueGuardException: 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 1398 1568 goto continuesearch; 1399 1569 } … … 1408 1578 */ 1409 1579 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 1410 1584 switch (pERepRec->ExceptionInfo[0]) 1411 1585 { 1412 1586 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]); 1414 1595 goto continueexecution; 1415 goto continuesearch; 1416 case XCPT_SIGNAL_INTR: 1417 if (InternalGenerateConsoleCtrlEvent(CTRL_C_EVENT, 0)) 1418 goto continueexecution; 1596 } 1419 1597 goto continuesearch; 1420 1598 … … 1424 1602 } 1425 1603 goto CrashAndBurn; 1604 } 1426 1605 1427 1606 default: //non-continuable exceptions … … 1497 1676 USHORT sel = RestoreOS2FS(); 1498 1677 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) { 1501 1700 OS2UnsetExceptionHandler(pExceptionRegRec); 1502 1701 }
Note:
See TracChangeset
for help on using the changeset viewer.