Changeset 8835 for trunk/src/kernel32/exceptions.cpp
- Timestamp:
- Jul 5, 2002, 4:48:34 PM (23 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/exceptions.cpp
r8817 r8835 1 /* $Id: exceptions.cpp,v 1.6 1 2002-07-01 19:14:31sandervl Exp $ */1 /* $Id: exceptions.cpp,v 1.62 2002-07-05 14:48:34 sandervl Exp $ */ 2 2 3 3 /* … … 57 57 #include <stdlib.h> 58 58 #include <assert.h> 59 #include <time.h> 59 60 #include <string.h> 60 61 #include "exceptions.h" … … 63 64 #include "mmap.h" 64 65 #include <wprocess.h> 66 #include <win32api.h> 65 67 #include "oslibexcept.h" 66 68 #include "exceptstackdump.h" … … 74 76 #define CTRL_BREAK_EVENT 1 //#include <wincon.h> 75 77 #include "console.h" 78 #include "initterm.h" 76 79 77 80 … … 104 107 LONG WIN32API UnhandledExceptionFilter(PWINEXCEPTION_POINTERS lpexpExceptionInfo); 105 108 void KillWin32Process(void); 109 110 static void sprintfException(PEXCEPTIONREPORTRECORD pERepRec, PEXCEPTIONREGISTRATIONRECORD pERegRec, PCONTEXTRECORD pCtxRec, PVOID p, PSZ szTrapDump); 111 112 static char szTrapDump[2048] = {0}; 106 113 107 114 #ifdef DEBUG … … 555 562 LONG WIN32API UnhandledExceptionFilter(PWINEXCEPTION_POINTERS lpexpExceptionInfo) 556 563 { 557 char szModName[16]; 558 char message[128]; 559 ULONG iObj; 560 ULONG offObj; 561 HMODULE hmod; 562 DWORD rc; 563 564 #if 0 //not in use... 565 // @@@PH: experimental change to have more control over exception handling 566 #pragma pack(4) 567 typedef struct 568 { 569 ULONG cb; /* Size of fixed part of structure */ 570 HPOINTER hIcon; /* Icon handle */ 571 ULONG cButtons; /* Number of buttons */ 572 ULONG flStyle; /* Icon style flags (MB_ICONQUESTION, etc...)*/ 573 HWND hwndNotify; /* Reserved */ 574 MB2D mb2d[4]; /* Array of button definitions */ 575 } myMB2INFO; 576 #pragma pack() 577 578 myMB2INFO mb2InfoExceptionBox = { 20, // size of structure 579 NULLHANDLE, // icon handle 580 4, // number of buttons 581 MB_ICONHAND, // icon style 582 NULLHANDLE, // reserved 583 { {"continue ~search", 100, BS_PUSHBUTTON | BS_TEXT | BS_AUTOSIZE}, 584 {"continue ~execution", 101, BS_PUSHBUTTON | BS_TEXT | BS_AUTOSIZE}, 585 {"execute ~handler", 102, BS_PUSHBUTTON | BS_TEXT | BS_AUTOSIZE | BS_DEFAULT}, 586 {"~terminate process", 103, BS_PUSHBUTTON | BS_TEXT | BS_AUTOSIZE} } 587 }; 588 #endif 589 590 dprintf(("KERNEL32: Default UnhandledExceptionFilter, CurrentErrorMode=%X", CurrentErrorMode)); 591 592 // We must not care about ErrorMode here!! The app expects that its own 593 // UnhandledExceptionFilter will be cared even if it never touched ErrorMode. 594 if(CurrentUnhExceptionFlt) // && !(CurrentErrorMode & (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX))) 595 { 596 dprintf(("KERNEL32: Calling user UnhandledExceptionFilter")); 597 rc = CurrentUnhExceptionFlt(lpexpExceptionInfo); 598 if(rc != WINEXCEPTION_CONTINUE_SEARCH) 599 return rc; 600 } 601 602 603 if (DosQueryModFromEIP(&hmod, &iObj, sizeof(szModName), szModName, &offObj, (ULONG)lpexpExceptionInfo->ExceptionRecord->ExceptionAddress)) 604 sprintf(message, 605 "Unhandled exception 0x%08lx at address 0x%08lx. (DQMFEIP rc=%d)", 606 lpexpExceptionInfo->ExceptionRecord->ExceptionCode, 607 lpexpExceptionInfo->ExceptionRecord->ExceptionAddress); 608 else 609 { 610 if (iObj == -1) 611 { /* fault in DosAllocMem allocated memory, hence PE loader.. */ 612 Win32ImageBase * pMod; 613 if (WinExe && WinExe->insideModule((ULONG)lpexpExceptionInfo->ExceptionRecord->ExceptionAddress)) 614 pMod = WinExe; 615 else 616 pMod = Win32DllBase::findModuleByAddr((ULONG)lpexpExceptionInfo->ExceptionRecord->ExceptionAddress); 617 if (pMod != NULL) 618 { 619 szModName[0] = '\0'; 620 strncat(szModName, pMod->getModuleName(), sizeof(szModName) - 1); 621 iObj = 0xFF; 622 offObj = (ULONG)lpexpExceptionInfo->ExceptionRecord->ExceptionAddress 623 - (ULONG)pMod->getInstanceHandle(); 624 } 625 } 626 sprintf(message, 627 "Unhandled exception 0x%08lx at address 0x%08lx.\r" 628 "Mod: %s obj: 0x%2lx off:0x%08lx", 629 lpexpExceptionInfo->ExceptionRecord->ExceptionCode, 630 lpexpExceptionInfo->ExceptionRecord->ExceptionAddress, 631 szModName, iObj, offObj); 632 } 633 634 /* 635 rc = WinMessageBox2(HWND_DESKTOP, 636 HWND_DESKTOP, 637 message, 638 "Oh, nooo!", 639 0, 640 (PMB2INFO)&mb2InfoExceptionBox); 641 switch (rc) 642 { 643 case 100: 644 return WINEXCEPTION_CONTINUE_SEARCH; 645 646 case 101: 564 char szModName[16]; 565 char message[128]; 566 ULONG iObj; 567 ULONG offObj; 568 HMODULE hmod; 569 DWORD rc; 570 571 dprintf(("KERNEL32: Default UnhandledExceptionFilter, CurrentErrorMode=%X", CurrentErrorMode)); 572 573 // We must not care about ErrorMode here!! The app expects that its own 574 // UnhandledExceptionFilter will be cared even if it never touched ErrorMode. 575 if(CurrentUnhExceptionFlt) // && !(CurrentErrorMode & (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX))) 576 { 577 dprintf(("KERNEL32: Calling user UnhandledExceptionFilter")); 578 rc = CurrentUnhExceptionFlt(lpexpExceptionInfo); 579 if(rc != WINEXCEPTION_CONTINUE_SEARCH) 580 return rc; 581 } 582 583 584 if (DosQueryModFromEIP(&hmod, &iObj, sizeof(szModName), szModName, &offObj, (ULONG)lpexpExceptionInfo->ExceptionRecord->ExceptionAddress)) 585 sprintf(message, "Unhandled exception 0x%08lx at address 0x%08lx. (DQMFEIP rc=%d)", 586 lpexpExceptionInfo->ExceptionRecord->ExceptionCode, 587 lpexpExceptionInfo->ExceptionRecord->ExceptionAddress); 588 else 589 { 590 if (iObj == -1) 591 { /* fault in DosAllocMem allocated memory, hence PE loader.. */ 592 Win32ImageBase * pMod; 593 if (WinExe && WinExe->insideModule((ULONG)lpexpExceptionInfo->ExceptionRecord->ExceptionAddress)) 594 pMod = WinExe; 595 else 596 pMod = Win32DllBase::findModuleByAddr((ULONG)lpexpExceptionInfo->ExceptionRecord->ExceptionAddress); 597 if (pMod != NULL) 598 { 599 szModName[0] = '\0'; 600 strncat(szModName, pMod->getModuleName(), sizeof(szModName) - 1); 601 iObj = 0xFF; 602 offObj = (ULONG)lpexpExceptionInfo->ExceptionRecord->ExceptionAddress 603 - (ULONG)pMod->getInstanceHandle(); 604 } 605 } 606 sprintf(message, 607 "Unhandled exception 0x%08lx at address 0x%08lx.\r" 608 "Mod: %s obj: 0x%2lx off:0x%08lx", 609 lpexpExceptionInfo->ExceptionRecord->ExceptionCode, 610 lpexpExceptionInfo->ExceptionRecord->ExceptionAddress, 611 szModName, iObj, offObj); 612 } 613 614 rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, message, "Application Error", 615 0, MB_ABORTRETRYIGNORE | MB_ERROR); 616 switch (rc) 617 { 618 case MBID_IGNORE: 647 619 return WINEXCEPTION_CONTINUE_EXECUTION; 648 620 649 case 102: 650 return WINEXCEPTION_EXECUTE_HANDLER; 651 652 case 103: 621 case MBID_ABORT: 653 622 KillWin32Process(); 654 623 // fall-through 655 624 656 default: 625 case MBID_RETRY: 626 default: 657 627 return WINEXCEPTION_EXECUTE_HANDLER; 658 } 659 */ 660 rc = WinMessageBox(HWND_DESKTOP, 661 HWND_DESKTOP, 662 message, 663 "Oh, nooo!", 664 0, 665 MB_ABORTRETRYIGNORE | MB_ERROR); 666 switch (rc) 667 { 668 case MBID_IGNORE: 669 return WINEXCEPTION_CONTINUE_EXECUTION; 670 671 case MBID_ABORT: 672 KillWin32Process(); 673 // fall-through 674 675 case MBID_RETRY: 676 default: 677 return WINEXCEPTION_EXECUTE_HANDLER; 678 } 679 } 680 681 628 } 629 } 682 630 /***************************************************************************** 683 631 * Name : LPTOP_LEVEL_EXCEPTION_FILTER WIN32API SetUnhandledExceptionFilter … … 719 667 720 668 //****************************************************************************** 721 extern "C" ULONG getEAX();722 extern "C" ULONG getEBX();723 669 VOID WIN32API ExitProcess(DWORD exitcode); 724 670 //****************************************************************************** 725 671 void KillWin32Process(void) 726 672 { 727 static BOOL fEntry = FALSE;728 729 if(fEntry == FALSE) {673 static BOOL fEntry = FALSE; 674 675 if(fEntry == FALSE) { 730 676 fEntry = TRUE; 731 677 ExitProcess(666); 732 678 return; 733 } 734 //Restore original OS/2 TIB selector 735 RestoreOS2FS(); 736 737 SetExceptionChain((ULONG)-1); 738 DosExit(EXIT_PROCESS, 666); 739 } 740 741 679 } 680 //Restore original OS/2 TIB selector 681 RestoreOS2FS(); 682 683 SetExceptionChain((ULONG)-1); 684 DosExit(EXIT_PROCESS, 666); 685 } 686 //***************************************************************************** 687 //***************************************************************************** 688 static void sprintfException(PEXCEPTIONREPORTRECORD pERepRec, 689 PEXCEPTIONREGISTRATIONRECORD pERegRec, 690 PCONTEXTRECORD pCtxRec, 691 PVOID p, 692 PSZ szTrapDump) 693 { 694 PSZ pszExceptionName = "<unknown>"; /* points to name/type excpt */ 695 APIRET rc = XCPT_CONTINUE_SEARCH; /* excpt-dep. code */ 696 BOOL fExcptSoftware = FALSE; /* software/hardware gen. exceptn */ 697 BOOL fExcptFatal = TRUE; /* fatal exception ? */ 698 BOOL fExcptPortable = TRUE; /* portability of exception */ 699 PPIB pPIB; /* process information block */ 700 PTIB pTIB; /* thread information block */ 701 ULONG ulModule; /* module number */ 702 ULONG ulObject; /* object number within the module */ 703 CHAR szModule[260]; /* buffer for the module name */ 704 ULONG ulOffset; /* offset within the object within the module */ 705 char szLineException[128]; 706 char szLineExceptionType[128]; 707 708 szLineException[0] = 0; /* initialize */ 709 szLineExceptionType[0] = 0; /* initialize */ 710 switch(pERepRec->ExceptionNum) /* take according action */ 711 { 712 /* portable, non-fatal software-generated exceptions */ 713 case XCPT_GUARD_PAGE_VIOLATION: 714 strcpy(szLineException, "Guard Page Violation"); 715 sprintf(szLineExceptionType, "R/W %08xh at %08xh.", pERepRec->ExceptionInfo[0], pERepRec->ExceptionInfo[1]); 716 fExcptSoftware = TRUE; 717 fExcptFatal = FALSE; 718 rc = XCPT_CONTINUE_EXECUTION; 719 break; 720 721 case XCPT_UNABLE_TO_GROW_STACK: 722 strcpy(szLineException, "Unable To Grow Stack"); 723 fExcptSoftware = TRUE; 724 fExcptFatal = FALSE; 725 rc = XCPT_CONTINUE_EXECUTION; 726 break; 727 728 /* portable, fatal, hardware-generated exceptions */ 729 case XCPT_ACCESS_VIOLATION: 730 strcpy(szLineException, "Access Violation"); 731 switch (pERepRec->ExceptionInfo[0]) 732 { 733 case XCPT_READ_ACCESS: 734 sprintf (szLineExceptionType, "Read Access at address %08xh", pERepRec->ExceptionInfo[1]); 735 break; 736 737 case XCPT_WRITE_ACCESS: 738 sprintf (szLineExceptionType, "Write Access at address %08x", pERepRec->ExceptionInfo[1]); 739 break; 740 741 case XCPT_SPACE_ACCESS: 742 sprintf (szLineExceptionType, "Space Access at selector %08x", pERepRec->ExceptionInfo[1]); 743 break; 744 745 case XCPT_LIMIT_ACCESS: 746 strcpy (szLineExceptionType, "Limit Access"); 747 break; 748 749 case XCPT_UNKNOWN_ACCESS: 750 strcpy (szLineExceptionType, "Unknown Access"); 751 break; 752 753 default: 754 strcpy (szLineExceptionType, "(Invalid Access Code)"); 755 break; 756 } 757 break; 758 759 case XCPT_INTEGER_DIVIDE_BY_ZERO: 760 strcpy(szLineException, "Division By Zero (Integer)"); 761 break; 762 763 case XCPT_FLOAT_DIVIDE_BY_ZERO: 764 strcpy(szLineException, "Division By Zero (Float)"); 765 break; 766 767 case XCPT_FLOAT_INVALID_OPERATION: 768 strcpy(szLineException, "Invalid Floating Point Operation"); 769 break; 770 771 case XCPT_ILLEGAL_INSTRUCTION: 772 strcpy(szLineException, "Illegal Instruction"); 773 break; 774 775 case XCPT_PRIVILEGED_INSTRUCTION: 776 strcpy(szLineException, "Privileged Instruction"); 777 break; 778 779 case XCPT_INTEGER_OVERFLOW: 780 strcpy(szLineException, "Integer Overflow"); 781 break; 782 783 case XCPT_FLOAT_OVERFLOW: 784 strcpy(szLineException, "Floating Point Overflow"); 785 break; 786 787 case XCPT_FLOAT_UNDERFLOW: 788 strcpy(szLineException, "Floating Point Underflow"); 789 break; 790 791 case XCPT_FLOAT_DENORMAL_OPERAND: 792 strcpy(szLineException, "Floating Point Denormal Operand"); 793 break; 794 795 case XCPT_FLOAT_INEXACT_RESULT: 796 strcpy(szLineException, "Floating Point Inexact Result"); 797 break; 798 799 case XCPT_FLOAT_STACK_CHECK: 800 strcpy(szLineException, "Floating Point Stack Check"); 801 break; 802 803 case XCPT_DATATYPE_MISALIGNMENT: 804 strcpy(szLineException, "Datatype Misalignment"); 805 sprintf(szLineExceptionType, "R/W %08x alignment %08x at %08x.", pERepRec->ExceptionInfo[0], 806 pERepRec->ExceptionInfo[1], pERepRec->ExceptionInfo[2]); 807 break; 808 809 case XCPT_BREAKPOINT: 810 strcpy(szLineException, "Breakpoint (DEBUG)"); 811 break; 812 813 case XCPT_SINGLE_STEP: 814 strcpy(szLineException, "Single Step (DEBUG)"); 815 break; 816 817 /* portable, fatal, software-generated exceptions */ 818 case XCPT_IN_PAGE_ERROR: 819 strcpy(szLineException, "In Page Error"); 820 sprintf(szLineExceptionType, "at %08x.", pERepRec->ExceptionInfo[0]); 821 fExcptSoftware = TRUE; 822 break; 823 824 case XCPT_PROCESS_TERMINATE: 825 strcpy(szLineException, "Process Termination"); 826 fExcptSoftware = TRUE; 827 break; 828 829 case XCPT_ASYNC_PROCESS_TERMINATE: 830 strcpy(szLineException, "Process Termination (async)"); 831 sprintf(szLineExceptionType, "terminating thread TID=%u", pERepRec->ExceptionInfo[0]); 832 fExcptSoftware = TRUE; 833 break; 834 835 case XCPT_NONCONTINUABLE_EXCEPTION: 836 strcpy(szLineException, "Noncontinuable Exception"); 837 fExcptSoftware = TRUE; 838 break; 839 840 case XCPT_INVALID_DISPOSITION: 841 strcpy(szLineException, "Invalid Disposition"); 842 fExcptSoftware = TRUE; 843 break; 844 845 /* non-portable, fatal exceptions */ 846 case XCPT_INVALID_LOCK_SEQUENCE: 847 strcpy(szLineException, "Invalid Lock Sequence"); 848 fExcptSoftware = TRUE; 849 fExcptPortable = FALSE; 850 break; 851 852 case XCPT_ARRAY_BOUNDS_EXCEEDED: 853 strcpy(szLineException, "Array Bounds Exceeded"); 854 fExcptSoftware = TRUE; 855 fExcptPortable = FALSE; 856 break; 857 858 /* unwind operation exceptions */ 859 case XCPT_UNWIND: 860 strcpy(szLineException, "Unwind Exception"); 861 fExcptSoftware = TRUE; 862 fExcptPortable = FALSE; 863 break; 864 865 case XCPT_BAD_STACK: 866 strcpy(szLineException, "Unwind Exception, Bad Stack"); 867 fExcptSoftware = TRUE; 868 fExcptPortable = FALSE; 869 break; 870 871 case XCPT_INVALID_UNWIND_TARGET: 872 strcpy(szLineException, "Unwind Exception, Invalid Target"); 873 fExcptSoftware = TRUE; 874 fExcptPortable = FALSE; 875 break; 876 877 /* fatal signal exceptions */ 878 case XCPT_SIGNAL: 879 strcpy(szLineException, "Signal"); 880 sprintf(szLineExceptionType, "Signal Number = %08x", pERepRec->ExceptionInfo[0]); 881 fExcptSoftware = TRUE; 882 fExcptPortable = FALSE; 883 884 switch (pERepRec->ExceptionInfo[0]) /* resolve signal information */ 885 { 886 case XCPT_SIGNAL_INTR: 887 strcpy(szLineException, "Signal (Interrupt)"); 888 break; 889 890 case XCPT_SIGNAL_KILLPROC: 891 strcpy(szLineException, "Signal (Kill Process)"); 892 break; 893 894 case XCPT_SIGNAL_BREAK: 895 strcpy(szLineException, "Signal (Break)"); 896 break; 897 } 898 break; 899 900 default: 901 strcpy(szLineException, "(unknown exception code)"); 902 sprintf(szLineExceptionType, "Exception Code = %08x", pERepRec->ExceptionNum); 903 break; 904 } 905 906 sprintf(szTrapDump, "---[Exception Information]------------\n %s", szLineException); 907 908 strcat(szTrapDump, " ("); 909 910 if (fExcptSoftware == TRUE) /* software or hardware generated ? */ 911 strcat (szTrapDump, "software generated,"); 912 else 913 strcat (szTrapDump, "hardware generated,"); 914 915 if (fExcptPortable == TRUE) /* portable exception ? */ 916 strcat (szTrapDump, "portable,"); 917 else 918 strcat (szTrapDump, "non-portable,"); 919 920 if (fExcptFatal == TRUE) /* fatal exception ? */ 921 strcat (szTrapDump, "fatal"); 922 else 923 strcat (szTrapDump, "non-fatal"); 924 925 strcat(szTrapDump, ")\n"); /* add trailing brace */ 926 927 928 rc = DosQueryModFromEIP(&ulModule, &ulObject, sizeof(szModule), 929 szModule, &ulOffset, (ULONG)pERepRec->ExceptionAddress); 930 931 sprintf(szLineException, " Exception Address = %08x ", pERepRec->ExceptionAddress); 932 strcat(szTrapDump, szLineException); 933 934 if(rc == NO_ERROR && ulObject != -1) 935 { 936 sprintf(szLineException, "<%.*s> (#%u) obj #%u:%08x\n", 64, szModule, ulModule, ulObject, ulOffset); 937 strcat(szTrapDump, szLineException); 938 } 939 else 940 { /* fault in DosAllocMem allocated memory, hence PE loader.. */ 941 Win32ImageBase * pMod; 942 if (WinExe && WinExe->insideModule((ULONG)pERepRec->ExceptionAddress)) 943 pMod = WinExe; 944 else 945 pMod = Win32DllBase::findModuleByAddr((ULONG)pERepRec->ExceptionAddress); 946 if (pMod != NULL) 947 { 948 szModule[0] = '\0'; 949 strncat(szModule, pMod->getModuleName(), sizeof(szModule) - 1); 950 ulObject = 0xFF; 951 ulOffset = (ULONG)pERepRec->ExceptionAddress - (ULONG)pMod->getInstanceHandle(); 952 sprintf(szLineException, "<%.*s> (#%u) obj #%u:%08x\n", 64, szModule, ulModule, ulObject, ulOffset); 953 } 954 else sprintf(szLineException, "<unknown win32 module>\n"); 955 956 strcat(szTrapDump, szLineException); 957 } 958 959 rc = DosGetInfoBlocks (&pTIB, &pPIB); 960 if (rc == NO_ERROR) 961 { 962 sprintf(szLineException, " Thread: Ordinal TID: %u, TID: %u, Priority: %04xh\n", 963 pTIB->tib_ordinal, pTIB->tib_ptib2->tib2_ultid, pTIB->tib_ptib2->tib2_ulpri); 964 strcat(szTrapDump, szLineException); 965 966 sprintf(szLineException, " Process: PID: %u, Parent: %u, Status: %u\n", pPIB->pib_ulpid, 967 pPIB->pib_ulppid, pPIB->pib_flstatus); 968 strcat(szTrapDump, szLineException); 969 } 970 971 if (pCtxRec->ContextFlags & CONTEXT_CONTROL) { /* check flags */ 972 sprintf(szLineException, " SS:ESP=%04x:%08x EFLAGS=%08x\n", pCtxRec->ctx_SegSs, pCtxRec->ctx_RegEsp, 973 pCtxRec->ctx_EFlags); 974 strcat(szTrapDump, szLineException); 975 sprintf(szLineException, " CS:EIP=%04x:%08x EBP =%08x\n", pCtxRec->ctx_SegCs, pCtxRec->ctx_RegEip, 976 pCtxRec->ctx_RegEbp); 977 strcat(szTrapDump, szLineException); 978 } 979 980 if (pCtxRec->ContextFlags & CONTEXT_INTEGER) { /* check flags */ 981 sprintf(szLineException, " EAX=%08x EBX=%08x ESI=%08x\n", pCtxRec->ctx_RegEax, pCtxRec->ctx_RegEbx, 982 pCtxRec->ctx_RegEsi); 983 strcat(szTrapDump, szLineException); 984 sprintf(szLineException, " ECX=%08x EDX=%08x EDI=%08x\n", pCtxRec->ctx_RegEcx, pCtxRec->ctx_RegEdx, 985 pCtxRec->ctx_RegEdi); 986 strcat(szTrapDump, szLineException); 987 } 988 989 if (pCtxRec->ContextFlags & CONTEXT_SEGMENTS) { /* check flags */ 990 sprintf(szLineException, " DS=%04x ES=%08x FS=%04x GS=%04x\n", pCtxRec->ctx_SegDs, pCtxRec->ctx_SegEs, pCtxRec->ctx_SegFs, pCtxRec->ctx_SegGs); 991 strcat(szTrapDump, szLineException); 992 } 993 994 if (pCtxRec->ContextFlags & CONTEXT_FLOATING_POINT) /* check flags */ 995 { 996 ULONG ulCounter; /* temporary local counter for fp stack */ 997 998 sprintf(szLineException, " Env[0]=%08x Env[1]=%08x Env[2]=%08x Env[3]=%08x\n", 999 pCtxRec->ctx_env[0], pCtxRec->ctx_env[1], 1000 pCtxRec->ctx_env[2], pCtxRec->ctx_env[3]); 1001 strcat(szTrapDump, szLineException); 1002 1003 sprintf(szLineException, " Env[4]=%08x Env[5]=%08x Env[6]=%08x\n", 1004 pCtxRec->ctx_env[4], pCtxRec->ctx_env[5], pCtxRec->ctx_env[6]); 1005 strcat(szTrapDump, szLineException); 1006 1007 for (ulCounter = 0; ulCounter < 8; /* see TOOLKIT\INCLUDE\BSEEXPT.H, _CONTEXT structure */ 1008 ulCounter ++) 1009 { 1010 sprintf(szLineException, " FP-Stack[%u] losig=%08x hisig=%08x signexp=%04x\n", 1011 ulCounter, pCtxRec->ctx_stack[0].losig, pCtxRec->ctx_stack[0].hisig, 1012 pCtxRec->ctx_stack[0].signexp); 1013 strcat(szTrapDump, szLineException); 1014 } 1015 } 1016 sprintf(szLineException, "---[End Of Exception Information]-----\n"); 1017 strcat(szTrapDump, szLineException); 1018 } 742 1019 /***************************************************************************** 743 1020 * Name : void static dprintfException … … 757 1034 PVOID p) 758 1035 { 759 PSZ pszExceptionName = "<unknown>"; /* points to name/type excpt */ 760 char szData[128]; /* local storage for excpt dep. information */ 761 char szData2[128]; /* local storage for excpt dep. information */ 762 APIRET rc = XCPT_CONTINUE_SEARCH; /* excpt-dep. code */ 763 BOOL fExcptSoftware = FALSE; /* software/hardware gen. exceptn */ 764 BOOL fExcptFatal = TRUE; /* fatal exception ? */ 765 BOOL fExcptPortable = TRUE; /* portability of exception */ 766 PPIB pPIB; /* process information block */ 767 PTIB pTIB; /* thread information block */ 768 ULONG ulModule; /* module number */ 769 ULONG ulObject; /* object number within the module */ 770 CHAR szModule[260]; /* buffer for the module name */ 771 ULONG ulOffset; /* offset within the object within the module */ 772 773 szData[0] = 0; /* initialize */ 774 szData2[0] = 0; /* initialize */ 775 switch(pERepRec->ExceptionNum) /* take according action */ 776 { 777 /* portable, non-fatal software-generated exceptions */ 778 case XCPT_GUARD_PAGE_VIOLATION: 779 pszExceptionName = "Guard Page Violation"; 780 sprintf(szData, 781 "R/W %08xh at %08xh.", 782 pERepRec->ExceptionInfo[0], 783 pERepRec->ExceptionInfo[1]); 784 fExcptSoftware = TRUE; 785 fExcptFatal = FALSE; 786 rc = XCPT_CONTINUE_EXECUTION; 787 break; 788 789 case XCPT_UNABLE_TO_GROW_STACK: 790 pszExceptionName = "Unable To Grow Stack"; 791 fExcptSoftware = TRUE; 792 fExcptFatal = FALSE; 793 rc = XCPT_CONTINUE_EXECUTION; 794 break; 795 796 /* portable, fatal, hardware-generated exceptions */ 797 case XCPT_ACCESS_VIOLATION: 798 pszExceptionName = "Access Violation"; 799 /* sprintf (szData, "Access type %08x at %08x.", pERepRec->ExceptionInfo[0], 800 pERepRec->ExceptionInfo[1]); */ 801 switch (pERepRec->ExceptionInfo[0]) 802 { 803 case XCPT_READ_ACCESS: 804 sprintf (szData, 805 "Read Access at address %08xh", 806 pERepRec->ExceptionInfo[1]); 807 break; 808 809 case XCPT_WRITE_ACCESS: 810 sprintf (szData, 811 "Write Access at address %08x", 812 pERepRec->ExceptionInfo[1]); 813 break; 814 815 case XCPT_SPACE_ACCESS: 816 sprintf (szData, 817 "Space Access at selector %08x", 818 pERepRec->ExceptionInfo[1]); 819 break; 820 821 case XCPT_LIMIT_ACCESS: 822 strcpy (szData, 823 "Limit Access"); 824 break; 825 826 case XCPT_UNKNOWN_ACCESS: 827 strcpy (szData, 828 "Unknown Access"); 829 break; 830 831 default: 832 strcpy (szData, 833 "(Invalid Access Code)"); 834 break; 835 } 836 break; 837 838 case XCPT_INTEGER_DIVIDE_BY_ZERO: 839 pszExceptionName = "Division By Zero (Integer)"; 840 break; 841 842 case XCPT_FLOAT_DIVIDE_BY_ZERO: 843 pszExceptionName = "Division By Zero (Float)"; 844 break; 845 846 case XCPT_FLOAT_INVALID_OPERATION: 847 pszExceptionName = "Invalid Floating Point Operation"; 848 break; 849 850 case XCPT_ILLEGAL_INSTRUCTION: 851 pszExceptionName = "Illegal Instruction"; 852 break; 853 854 case XCPT_PRIVILEGED_INSTRUCTION: 855 pszExceptionName = "Privileged Instruction"; 856 break; 857 858 case XCPT_INTEGER_OVERFLOW: 859 pszExceptionName = "Integer Overflow"; 860 break; 861 862 case XCPT_FLOAT_OVERFLOW: 863 pszExceptionName = "Floating Point Overflow"; 864 break; 865 866 case XCPT_FLOAT_UNDERFLOW: 867 pszExceptionName = "Floating Point Underflow"; 868 break; 869 870 case XCPT_FLOAT_DENORMAL_OPERAND: 871 pszExceptionName = "Floating Point Denormal Operand"; 872 break; 873 874 case XCPT_FLOAT_INEXACT_RESULT: 875 pszExceptionName = "Floating Point Inexact Result"; 876 break; 877 878 case XCPT_FLOAT_STACK_CHECK: 879 pszExceptionName = "Floating Point Stack Check"; 880 break; 881 882 case XCPT_DATATYPE_MISALIGNMENT: 883 pszExceptionName = "Datatype Misalignment"; 884 sprintf(szData, 885 "R/W %08x alignment %08x at %08x.", 886 pERepRec->ExceptionInfo[0], 887 pERepRec->ExceptionInfo[1], 888 pERepRec->ExceptionInfo[2]); 889 break; 890 891 case XCPT_BREAKPOINT: 892 pszExceptionName = "Breakpoint (don't debug me! :)"; 893 break; 894 895 case XCPT_SINGLE_STEP: 896 pszExceptionName = "Single Step (don't debug me! :)"; 897 break; 898 899 /* portable, fatal, software-generated exceptions */ 900 case XCPT_IN_PAGE_ERROR: 901 pszExceptionName = "In Page Error"; 902 sprintf(szData, 903 "at %08x.", 904 pERepRec->ExceptionInfo[0]); 905 fExcptSoftware = TRUE; 906 break; 907 908 case XCPT_PROCESS_TERMINATE: 909 pszExceptionName = "Process Termination"; 910 fExcptSoftware = TRUE; 911 break; 912 913 case XCPT_ASYNC_PROCESS_TERMINATE: 914 pszExceptionName = "Process Termination (async)"; 915 sprintf(szData, 916 "terminating thread TID=%u", 917 pERepRec->ExceptionInfo[0]); 918 fExcptSoftware = TRUE; 919 break; 920 921 case XCPT_NONCONTINUABLE_EXCEPTION: 922 pszExceptionName = "Noncontinuable Exception"; 923 fExcptSoftware = TRUE; 924 break; 925 926 case XCPT_INVALID_DISPOSITION: 927 pszExceptionName = "Invalid Disposition"; 928 fExcptSoftware = TRUE; 929 break; 930 931 /* non-portable, fatal exceptions */ 932 case XCPT_INVALID_LOCK_SEQUENCE: 933 pszExceptionName = "Invalid Lock Sequence"; 934 fExcptSoftware = TRUE; 935 fExcptPortable = FALSE; 936 break; 937 938 case XCPT_ARRAY_BOUNDS_EXCEEDED: 939 pszExceptionName = "Array Bounds Exceeded"; 940 fExcptSoftware = TRUE; 941 fExcptPortable = FALSE; 942 break; 943 944 /* unwind operation exceptions */ 945 case XCPT_UNWIND: 946 pszExceptionName = "Unwind Exception"; 947 fExcptSoftware = TRUE; 948 fExcptPortable = FALSE; 949 break; 950 951 case XCPT_BAD_STACK: 952 pszExceptionName = "Unwind Exception, Bad Stack"; 953 fExcptSoftware = TRUE; 954 fExcptPortable = FALSE; 955 break; 956 957 case XCPT_INVALID_UNWIND_TARGET: 958 pszExceptionName = "Unwind Exception, Invalid Target"; 959 fExcptSoftware = TRUE; 960 fExcptPortable = FALSE; 961 break; 962 963 /* fatal signal exceptions */ 964 case XCPT_SIGNAL: 965 pszExceptionName = "Signal"; 966 sprintf(szData, 967 "Signal Number = %08x", 968 pERepRec->ExceptionInfo[0]); 969 fExcptSoftware = TRUE; 970 fExcptPortable = FALSE; 971 972 switch (pERepRec->ExceptionInfo[0]) /* resolve signal information */ 973 { 974 case XCPT_SIGNAL_INTR: 975 pszExceptionName = "Signal (Interrupt)"; 976 break; 977 978 case XCPT_SIGNAL_KILLPROC: 979 pszExceptionName = "Signal (Kill Process)"; 980 break; 981 982 case XCPT_SIGNAL_BREAK: 983 pszExceptionName = "Signal (Break)"; 984 break; 985 } 986 break; 987 988 default: 989 pszExceptionName = "(unknown exception code)"; 990 sprintf(szData, 991 "Exception Code = %08x", 992 pERepRec->ExceptionNum); 993 } 994 995 996 /* now dump the information to the logfile */ 997 dprintf(("---[Exception Information]------------\n")); 998 sprintf(szData2, 999 " %s (", 1000 pszExceptionName); 1001 1002 if (fExcptSoftware == TRUE) /* software or hardware generated ? */ 1003 strcat (szData2, "software generated,"); 1004 else 1005 strcat (szData2, "hardware generated,"); 1006 1007 if (fExcptPortable == TRUE) /* portable exception ? */ 1008 strcat (szData2, "portable,"); 1009 else 1010 strcat (szData2, "non-portable,"); 1011 1012 if (fExcptFatal == TRUE) /* fatal exception ? */ 1013 strcat (szData2, "fatal"); 1014 else 1015 strcat (szData2, "non-fatal"); 1016 1017 strcat (szData2, /* add trailing brace */ 1018 ")\n"); 1019 1020 1021 dprintf((szData2)); 1022 1023 if (szData[0] != 0) /* see if there is an additional entry */ 1024 dprintf((" %s\n", 1025 szData)); 1026 1027 rc = DosQueryModFromEIP(&ulModule, 1028 &ulObject, 1029 sizeof(szModule), 1030 szModule, 1031 &ulOffset, 1032 (ULONG)pERepRec->ExceptionAddress); 1033 1034 dprintf((" Exception Address = %08x ", 1035 pERepRec->ExceptionAddress)); 1036 1037 if(rc == NO_ERROR && ulObject != -1) 1038 { 1039 dprintf(("<%s> (#%u), obj #%u:%08x\n", 1040 szModule, 1041 ulModule, 1042 ulObject, 1043 ulOffset)); 1044 } 1045 else 1046 { /* fault in DosAllocMem allocated memory, hence PE loader.. */ 1047 Win32ImageBase * pMod; 1048 if (WinExe && WinExe->insideModule((ULONG)pERepRec->ExceptionAddress)) 1049 pMod = WinExe; 1050 else 1051 pMod = Win32DllBase::findModuleByAddr((ULONG)pERepRec->ExceptionAddress); 1052 if (pMod != NULL) 1053 { 1054 szModule[0] = '\0'; 1055 strncat(szModule, pMod->getModuleName(), sizeof(szModule) - 1); 1056 ulObject = 0xFF; 1057 ulOffset = (ULONG)pERepRec->ExceptionAddress - (ULONG)pMod->getInstanceHandle(); 1058 dprintf(("<%s> (#%u), obj #%u:%08x\n", 1059 szModule, ulModule, ulObject, ulOffset)); 1060 } 1061 else dprintf(("<unknown win32 module>\n")); 1062 } 1063 1064 rc = DosGetInfoBlocks (&pTIB, /* query kernel information blocks */ 1065 &pPIB); 1066 if (rc == NO_ERROR) 1067 { 1068 dprintf((" Thread: Ordinal TID: %u, TID: %u, Priority: %04xh\n", 1069 pTIB->tib_ordinal, 1070 pTIB->tib_ptib2->tib2_ultid, 1071 pTIB->tib_ptib2->tib2_ulpri)); 1072 1073 dprintf((" Process: PID: %u, Parent: %u, Status: %u\n", 1074 pPIB->pib_ulpid, 1075 pPIB->pib_ulppid, 1076 pPIB->pib_flstatus)); 1077 } 1078 1079 if (pCtxRec->ContextFlags & CONTEXT_CONTROL) /* check flags */ 1080 dprintf((" SS:ESP=%04x:%08x EFLAGS=%08x\n", 1081 pCtxRec->ctx_SegSs, 1082 pCtxRec->ctx_RegEsp, 1083 pCtxRec->ctx_EFlags)); 1084 dprintf((" CS:EIP=%04x:%08x EBP =%08x\n", 1085 pCtxRec->ctx_SegCs, 1086 pCtxRec->ctx_RegEip, 1087 pCtxRec->ctx_RegEbp)); 1088 1089 if (pCtxRec->ContextFlags & CONTEXT_INTEGER) /* check flags */ 1090 dprintf((" EAX=%08x EBX=%08x ESI=%08x\n", 1091 pCtxRec->ctx_RegEax, 1092 pCtxRec->ctx_RegEbx, 1093 pCtxRec->ctx_RegEsi)); 1094 dprintf((" ECX=%08x EDX=%08x EDI=%08x\n", 1095 pCtxRec->ctx_RegEcx, 1096 pCtxRec->ctx_RegEdx, 1097 pCtxRec->ctx_RegEdi)); 1098 1099 if (pCtxRec->ContextFlags & CONTEXT_SEGMENTS) /* check flags */ 1100 dprintf((" DS=%04x ES=%08x", 1101 pCtxRec->ctx_SegDs, 1102 pCtxRec->ctx_SegEs)); 1103 dprintf((" FS=%04x GS=%04x\n", 1104 pCtxRec->ctx_SegFs, 1105 pCtxRec->ctx_SegGs)); 1106 1107 if (pCtxRec->ContextFlags & CONTEXT_FLOATING_POINT) /* check flags */ 1108 { 1109 ULONG ulCounter; /* temporary local counter for fp stack */ 1110 1111 dprintf((" Env[0]=%08x Env[1]=%08x Env[2]=%08x Env[3]=%08x\n", 1112 pCtxRec->ctx_env[0], 1113 pCtxRec->ctx_env[1], 1114 pCtxRec->ctx_env[2], 1115 pCtxRec->ctx_env[3])); 1116 1117 dprintf((" Env[4]=%08x Env[5]=%08x Env[6]=%08x\n", 1118 pCtxRec->ctx_env[4], 1119 pCtxRec->ctx_env[5], 1120 pCtxRec->ctx_env[6])); 1121 1122 for (ulCounter = 0; 1123 ulCounter < 8; /* see TOOLKIT\INCLUDE\BSEEXPT.H, _CONTEXT structure */ 1124 ulCounter ++) 1125 dprintf((" FP-Stack[%u] losig=%08x hisig=%08x signexp=%04x\n", 1126 ulCounter, 1127 pCtxRec->ctx_stack[0].losig, 1128 pCtxRec->ctx_stack[0].hisig, 1129 pCtxRec->ctx_stack[0].signexp)); 1130 } 1131 1132 dprintf(("---[End Of Exception Information]-----\n")); 1036 /* now dump the information to the logfile */ 1037 dprintf(("\n%s", szTrapDump)); 1038 } 1039 //***************************************************************************** 1040 static char szExceptionLogFileName[CCHMAXPATH] = ""; 1041 static BOOL fExceptionLoggging = TRUE; 1042 //***************************************************************************** 1043 //Override filename of exception log (expects full path) 1044 //***************************************************************************** 1045 void WIN32API SetCustomExceptionLog(LPSTR lpszLogName) 1046 { 1047 strcpy(szExceptionLogFileName, lpszLogName); 1048 } 1049 //***************************************************************************** 1050 //***************************************************************************** 1051 void WIN32API SetExceptionLogging(BOOL fEnable) 1052 { 1053 fExceptionLoggging = fEnable; 1054 } 1055 //***************************************************************************** 1056 //***************************************************************************** 1057 static void logException() 1058 { 1059 APIRET rc; 1060 HFILE hFile; 1061 ULONG ulAction, ulBytesWritten; 1062 1063 if(fExceptionLoggging == FALSE) { 1064 return; 1065 } 1066 1067 if(szExceptionLogFileName[0] == 0) { 1068 strcpy(szExceptionLogFileName, kernel32Path); 1069 strcat(szExceptionLogFileName, "\\exception.log"); 1070 } 1071 rc = DosOpen(szExceptionLogFileName, /* File path name */ 1072 &hFile, /* File handle */ 1073 &ulAction, /* Action taken */ 1074 0L, /* File primary allocation */ 1075 0L, /* File attribute */ 1076 OPEN_ACTION_CREATE_IF_NEW | 1077 OPEN_ACTION_OPEN_IF_EXISTS, /* Open function type */ 1078 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, 1079 0L); /* No extended attribute */ 1080 1081 if(rc == NO_ERROR) { 1082 DosSetFilePtr(hFile, 0, FILE_END, &ulBytesWritten); 1083 if(WinExe) { 1084 LPSTR lpszExeName; 1085 1086 lpszExeName = WinExe->getModuleName(); 1087 1088 if(lpszExeName) { 1089 DosWrite(hFile, "\n", 2, &ulBytesWritten); 1090 DosWrite(hFile, lpszExeName, strlen(lpszExeName), &ulBytesWritten); 1091 DosWrite(hFile, "\n", 2, &ulBytesWritten); 1092 } 1093 } 1094 LPSTR lpszTime; 1095 time_t curtime; 1096 1097 curtime = time(NULL); 1098 lpszTime = asctime(localtime(&curtime)); 1099 if(lpszTime) { 1100 DosWrite(hFile, lpszTime, strlen(lpszTime), &ulBytesWritten); 1101 } 1102 DosWrite(hFile, szTrapDump, strlen(szTrapDump), &ulBytesWritten); 1103 DosClose(hFile); 1104 } 1133 1105 } 1134 1106 … … 1154 1126 PVOID p) 1155 1127 { 1156 //SvL: Check if exception inside debug fprintf -> if so, clear lock so 1157 // next dprintf won't wait forever 1158 int prevlock = LogException(ENTER_EXCEPTION); 1159 1160 /* Access violation at a known location */ 1161 switch(pERepRec->ExceptionNum) 1162 { 1163 case XCPT_FLOAT_DENORMAL_OPERAND: 1164 case XCPT_FLOAT_DIVIDE_BY_ZERO: 1165 case XCPT_FLOAT_INEXACT_RESULT: 1128 //SvL: Check if exception inside debug fprintf -> if so, clear lock so 1129 // next dprintf won't wait forever 1130 int prevlock = LogException(ENTER_EXCEPTION); 1131 1132 //print exception name & exception type 1133 sprintfException(pERepRec, pERegRec, pCtxRec, p, szTrapDump); 1134 logException(); 1135 1136 1137 /* Access violation at a known location */ 1138 switch(pERepRec->ExceptionNum) 1139 { 1140 case XCPT_FLOAT_DENORMAL_OPERAND: 1141 case XCPT_FLOAT_DIVIDE_BY_ZERO: 1142 case XCPT_FLOAT_INEXACT_RESULT: 1166 1143 // case XCPT_FLOAT_INVALID_OPERATION: 1167 case XCPT_FLOAT_OVERFLOW:1168 case XCPT_FLOAT_STACK_CHECK:1169 case XCPT_FLOAT_UNDERFLOW:1144 case XCPT_FLOAT_OVERFLOW: 1145 case XCPT_FLOAT_STACK_CHECK: 1146 case XCPT_FLOAT_UNDERFLOW: 1170 1147 dprintfException(pERepRec, pERegRec, pCtxRec, p); 1171 1148 dprintf(("KERNEL32: OS2ExceptionHandler: FPU exception\n")); … … 1188 1165 } 1189 1166 1190 case XCPT_PROCESS_TERMINATE:1191 case XCPT_ASYNC_PROCESS_TERMINATE:1167 case XCPT_PROCESS_TERMINATE: 1168 case XCPT_ASYNC_PROCESS_TERMINATE: 1192 1169 //// dprintfException(pERepRec, pERegRec, pCtxRec, p); 1193 1170 SetExceptionChain((ULONG)-1); 1194 1171 goto continuesearch; 1195 1172 1196 case XCPT_ACCESS_VIOLATION:1197 {1173 case XCPT_ACCESS_VIOLATION: 1174 { 1198 1175 Win32MemMap *map; 1199 1176 BOOL fWriteAccess = FALSE; … … 1260 1237 1261 1238 //no break; 1262 }1239 } 1263 1240 continueFail: 1264 1241 1265 1242 ////#define DEBUGSTACK 1266 1243 #ifdef DEBUGSTACK 1267 if(pCtxRec->ContextFlags & CONTEXT_CONTROL) {1244 if(pCtxRec->ContextFlags & CONTEXT_CONTROL) { 1268 1245 ULONG *stackptr; 1269 1246 APIRET rc; … … 1288 1265 } 1289 1266 dprintf(("Stack DUMP END")); 1290 }1267 } 1291 1268 #endif 1292 1269 1293 case XCPT_BREAKPOINT:1294 case XCPT_ARRAY_BOUNDS_EXCEEDED:1295 case XCPT_DATATYPE_MISALIGNMENT:1296 case XCPT_ILLEGAL_INSTRUCTION:1297 case XCPT_PRIVILEGED_INSTRUCTION:1298 case XCPT_INVALID_LOCK_SEQUENCE:1299 case XCPT_INTEGER_DIVIDE_BY_ZERO:1300 case XCPT_INTEGER_OVERFLOW:1301 case XCPT_SINGLE_STEP:1302 case XCPT_UNABLE_TO_GROW_STACK:1303 case XCPT_IN_PAGE_ERROR:1270 case XCPT_BREAKPOINT: 1271 case XCPT_ARRAY_BOUNDS_EXCEEDED: 1272 case XCPT_DATATYPE_MISALIGNMENT: 1273 case XCPT_ILLEGAL_INSTRUCTION: 1274 case XCPT_PRIVILEGED_INSTRUCTION: 1275 case XCPT_INVALID_LOCK_SEQUENCE: 1276 case XCPT_INTEGER_DIVIDE_BY_ZERO: 1277 case XCPT_INTEGER_OVERFLOW: 1278 case XCPT_SINGLE_STEP: 1279 case XCPT_UNABLE_TO_GROW_STACK: 1280 case XCPT_IN_PAGE_ERROR: 1304 1281 CrashAndBurn: 1305 1282 //SvL: TODO: this may not always be the right thing to do … … 1332 1309 goto continueexecution; 1333 1310 1334 //@@@PH: growing thread stacks might need special treatment1335 case XCPT_GUARD_PAGE_VIOLATION:1311 //@@@PH: growing thread stacks might need special treatment 1312 case XCPT_GUARD_PAGE_VIOLATION: 1336 1313 //SvL: don't print anything here -> fatal hang if happens inside fprintf 1337 1314 //dprintf(("KERNEL32: OS2ExceptionHandler: trying to grow stack (continue search)")); … … 1364 1341 goto CrashAndBurn; 1365 1342 1366 default: //non-continuable exceptions1343 default: //non-continuable exceptions 1367 1344 dprintfException(pERepRec, pERegRec, pCtxRec, p); 1368 1345 goto continuesearch; 1369 }1346 } 1370 1347 continuesearch: 1371 LogException(LEAVE_EXCEPTION, prevlock);1372 return XCPT_CONTINUE_SEARCH;1348 LogException(LEAVE_EXCEPTION, prevlock); 1349 return XCPT_CONTINUE_SEARCH; 1373 1350 1374 1351 continueexecution: 1375 LogException(LEAVE_EXCEPTION, prevlock);1376 return XCPT_CONTINUE_EXECUTION;1352 LogException(LEAVE_EXCEPTION, prevlock); 1353 return XCPT_CONTINUE_EXECUTION; 1377 1354 } 1378 1355 … … 1404 1381 #endif 1405 1382 } 1406 1383 //***************************************************************************** 1384 //***************************************************************************** 1407 1385 #ifdef DEBUG 1408 1386 void PrintExceptionChain() … … 1418 1396 SetFS(sel); 1419 1397 } 1420 1398 //***************************************************************************** 1399 //***************************************************************************** 1421 1400 void PrintWin32ExceptionChain(PWINEXCEPTION_FRAME pframe) 1422 1401 { … … 1456 1435 #endif 1457 1436 } 1458 1437 //***************************************************************************** 1438 //***************************************************************************** 1459 1439 void SetOS2ExceptionChain(ULONG val) 1460 1440 { … … 1464 1444 SetFS(sel); 1465 1445 } 1466 1446 //***************************************************************************** 1447 //***************************************************************************** 1467 1448 int _System CheckCurFS() 1468 1449 { … … 1482 1463 return TRUE; 1483 1464 } 1484 1465 //***************************************************************************** 1466 //***************************************************************************** 1467
Note:
See TracChangeset
for help on using the changeset viewer.