Changeset 149
- Timestamp:
- Nov 1, 2006, 7:18:21 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/tools/qsysxcpt_pm.cpp
r148 r149 60 60 // contexts to the trap file when a real exception happens on one thread 61 61 62 /* ! \class QtOS2SysXcptMainHandler qt_os2.h63 64 65 66 67 68 69 70 */62 /** @class QtOS2SysXcptMainHandler qt_os2.h 63 * 64 * @todo (r=dmik) describe... 65 * 66 * - must be instantiated on the stack of the main thread only 67 * - should be instantiated before a QAplication instance is created 68 * (does nothing otherwise) 69 * - note that callback can be called on any thread 70 */ 71 71 72 72 /* static */ … … 75 75 ERR QtOS2SysXcptMainHandler::libcHandler = NULL; 76 76 77 /* !78 79 */80 QtOS2SysXcptMainHandler::QtOS2SysXcptMainHandler ( QtOS2SysXcptCallback cb)77 /** 78 * @todo (r=dmik) describe... 79 */ 80 QtOS2SysXcptMainHandler::QtOS2SysXcptMainHandler (QtOS2SysXcptCallback cb) 81 81 { 82 82 rec.prev_structure = NULL; … … 84 84 85 85 PTIB ptib = NULL; 86 DosGetInfoBlocks ( &ptib, NULL);87 Q_ASSERT ( ptib && ptib->tib_ptib2);88 89 if ( ptib && ptib->tib_ptib2)90 { 91 / / must be instantiated only on the main (first) thread92 Q_ASSERT ( ptib->tib_ptib2->tib2_ultid == 1);93 if ( ptib->tib_ptib2->tib2_ultid == 1)94 { 95 / / must not be already instantiated96 Q_ASSERT ( installed == FALSE);97 Q_ASSERT ( libcHandler == NULL);98 if ( installed == FALSE && libcHandler == NULL)86 DosGetInfoBlocks (&ptib, NULL); 87 Q_ASSERT (ptib && ptib->tib_ptib2); 88 89 if (ptib && ptib->tib_ptib2) 90 { 91 /* must be instantiated only on the main (first) thread */ 92 Q_ASSERT (ptib->tib_ptib2->tib2_ultid == 1); 93 if (ptib->tib_ptib2->tib2_ultid == 1) 94 { 95 /* must not be already instantiated */ 96 Q_ASSERT (installed == FALSE); 97 Q_ASSERT (libcHandler == NULL); 98 if (installed == FALSE && libcHandler == NULL) 99 99 { 100 100 installed = TRUE; 101 101 callback = cb; 102 / / install the exception handler for the main thread102 /* install the exception handler for the main thread */ 103 103 rec.ExceptionHandler = handler; 104 DosSetExceptionHandler ( &rec);105 } 106 } 107 } 108 } 109 110 /* !111 112 */104 DosSetExceptionHandler (&rec); 105 } 106 } 107 } 108 } 109 110 /** 111 * @todo (r=dmik) describe... 112 */ 113 113 QtOS2SysXcptMainHandler::~QtOS2SysXcptMainHandler() 114 114 { 115 Q_ASSERT ( rec.ExceptionHandler == handler || rec.ExceptionHandler == NULL);116 if ( rec.ExceptionHandler == handler)117 { 118 / / uninstall the exception handler for the main thread119 DosUnsetExceptionHandler ( &rec);115 Q_ASSERT (rec.ExceptionHandler == handler || rec.ExceptionHandler == NULL); 116 if (rec.ExceptionHandler == handler) 117 { 118 /* uninstall the exception handler for the main thread */ 119 DosUnsetExceptionHandler (&rec); 120 120 rec.ExceptionHandler = NULL; 121 121 callback = NULL; … … 124 124 } 125 125 126 static void qt_excEscapeString ( FILE *file, const char *pcszStr);126 static void qt_excEscapeString (FILE *file, const char *pcszStr); 127 127 128 128 #define XcptPvt QtOS2SysXcptMainHandler::Private … … 131 131 { 132 132 public: 133 static void callbackWriter ( const char *msg);134 135 static inline int askCallback ( QtOS2SysXcptReq req)136 { 137 if ( callback)138 return callback ( req, NULL, 0);133 static void callbackWriter (const char *msg); 134 135 static inline int askCallback (QtOS2SysXcptReq req) 136 { 137 if (callback) 138 return callback (req, NULL, 0); 139 139 return FALSE; 140 140 } 141 141 142 static inline int letCallback ( QtOS2SysXcptReq req)143 { 144 if ( callback)145 return callback ( req, callbackWriter, 0);142 static inline int letCallback (QtOS2SysXcptReq req) 143 { 144 if (callback) 145 return callback (req, callbackWriter, 0); 146 146 return FALSE; 147 147 } … … 154 154 155 155 /* static */ 156 void XcptPvt::callbackWriter ( const char *msg)157 { 158 if ( file)159 qt_excEscapeString ( file, msg);160 } 161 162 /* !\internal163 164 */165 static void qt_excEscapeString ( FILE *file, const char *pcszStr)156 void XcptPvt::callbackWriter (const char *msg) 157 { 158 if (file) 159 qt_excEscapeString (file, msg); 160 } 161 162 /** \internal 163 * Writes the given string with [<>&'"] characters escaped for XML. 164 */ 165 static void qt_excEscapeString (FILE *file, const char *pcszStr) 166 166 { 167 167 const char *pcszChars = "<>&'\""; … … 172 172 size_t cbLen = 0; 173 173 174 if ( !pcsz)174 if (!pcsz) 175 175 return; 176 176 177 while ( *pcsz)178 { 179 cbLen = strcspn ( pcsz, pcszChars);180 fwrite ( pcsz, 1, cbLen, file);177 while (*pcsz) 178 { 179 cbLen = strcspn (pcsz, pcszChars); 180 fwrite (pcsz, 1, cbLen, file); 181 181 pcsz += cbLen; 182 if ( !*pcsz)182 if (!*pcsz) 183 183 break; 184 cbLen = strchr ( pcszChars, *pcsz) - pcszChars;184 cbLen = strchr (pcszChars, *pcsz) - pcszChars; 185 185 pcszRepl = aszEntities[cbLen]; 186 fwrite ( pcszRepl, 1, strlen(pcszRepl), file);186 fwrite (pcszRepl, 1, strlen(pcszRepl), file); 187 187 ++ pcsz; 188 188 } 189 189 } 190 190 191 /* !\internal192 193 */194 static void qt_excWriteErrorMsg (FILE *file, ULONG ulIndent, const char *pcszMsg,195 ... 191 /** \internal 192 * Writes the given error message. 193 */ 194 static void qt_excWriteErrorMsg (FILE *file, ULONG ulIndent, const char *pcszMsg, 195 ...) 196 196 { 197 197 char szBuf[1024]; 198 198 va_list args; 199 va_start ( args, pcszMsg);200 fprintf ( file, "%*s<Error message=\"", ulIndent, "");201 vsnprintf ( szBuf, sizeof(szBuf), pcszMsg, args);199 va_start (args, pcszMsg); 200 fprintf (file, "%*s<Error message=\"", ulIndent, ""); 201 vsnprintf (szBuf, sizeof(szBuf), pcszMsg, args); 202 202 szBuf[sizeof(szBuf) - 1] = '\0'; 203 qt_excEscapeString ( file, szBuf);204 fprintf ( file, "\"/>\n");205 va_end ( args);206 } 207 208 /* !\internal209 210 */211 static void qt_excWriteReg (FILE *file, const char *pszName, ULONG ulValue,212 BOOL bQueryMem = TRUE 213 { 214 fprintf (file, " <Register name=\"%s\" value=\"%08lX\"",215 pszName, ulValue 216 217 if ( bQueryMem)203 qt_excEscapeString (file, szBuf); 204 fprintf (file, "\"/>\n"); 205 va_end (args); 206 } 207 208 /** \internal 209 * Writes the register name, value and optionally memory flags 210 */ 211 static void qt_excWriteReg (FILE *file, const char *pszName, ULONG ulValue, 212 BOOL bQueryMem = TRUE) 213 { 214 fprintf (file, " <Register name=\"%s\" value=\"%08lX\"", 215 pszName, ulValue); 216 217 if (bQueryMem) 218 218 { 219 219 APIRET arc; 220 220 ULONG ulCount = 4; 221 221 ULONG ulFlags = 0; 222 arc = DosQueryMem ( (PVOID) ulValue, &ulCount, &ulFlags);223 224 if ( arc == NO_ERROR || arc == ERROR_INVALID_ADDRESS)225 { 226 if ( arc == NO_ERROR)227 { 228 fprintf ( file, " flags=\"%08lX\"", ulFlags);229 if ( ulFlags & (PAG_COMMIT | PAG_READ) == (PAG_COMMIT | PAG_READ))230 fprintf ( file, " word=\"%08lX\"/>\n", *(ULONG *) ulValue);222 arc = DosQueryMem ((PVOID) ulValue, &ulCount, &ulFlags); 223 224 if (arc == NO_ERROR || arc == ERROR_INVALID_ADDRESS) 225 { 226 if (arc == NO_ERROR) 227 { 228 fprintf (file, " flags=\"%08lX\"", ulFlags); 229 if (ulFlags & (PAG_COMMIT | PAG_READ) == (PAG_COMMIT | PAG_READ)) 230 fprintf (file, " word=\"%08lX\"/>\n", *(ULONG *) ulValue); 231 231 else 232 fprintf ( file, "/>\n");232 fprintf (file, "/>\n"); 233 233 } 234 234 else 235 fprintf ( file, " flags=\"invalid\"/>\n");235 fprintf (file, " flags=\"invalid\"/>\n"); 236 236 } 237 237 else 238 238 { 239 fprintf ( file, ">\n");240 qt_excWriteErrorMsg (file, 7, "DosQueryMem returned %lu"241 "and flags %08lX", arc, ulFlags 242 fprintf ( file, " </Register>\n");239 fprintf (file, ">\n"); 240 qt_excWriteErrorMsg (file, 7, "DosQueryMem returned %lu" 241 "and flags %08lX", arc, ulFlags); 242 fprintf (file, " </Register>\n"); 243 243 } 244 244 } 245 245 else 246 fprintf ( file, "/>\n");247 } 248 249 /* !\internal250 251 */246 fprintf (file, "/>\n"); 247 } 248 249 /** \internal 250 * Writes information about a signle stack frame. 251 */ 252 252 static void qt_excWriteStackFrame (FILE *file, ULONG ulRegEbp, ULONG ulRegEip) 253 253 { … … 327 327 } 328 328 329 /* !\internal330 331 */329 /** \internal 330 * Walks the stack and writes information about stack frames. 331 */ 332 332 static void qt_excWriteStackFrames (FILE *file, PTIB ptib, 333 333 PCONTEXTRECORD pContextRec) … … 383 383 } 384 384 385 /* !\internal386 387 388 389 */385 /** \internal 386 * Writes the thread information. 387 * If ptib is not NULL, the current thread's information is to be written. 388 * If ptib is NULL, pThrdRec is guaranted not to be NULL. 389 */ 390 390 static void qt_excWriteThreadInfo (FILE *file, PTIB ptib, QSTREC *pThrdRec, 391 391 PCONTEXTRECORD pContextRec) … … 416 416 " <Registers>\n"); 417 417 418 if 418 if (pContextRec->ContextFlags & CONTEXT_SEGMENTS) 419 419 { 420 420 qt_excWriteReg (file, "DS", pContextRec->ctx_SegDs, FALSE); … … 424 424 } 425 425 426 if 426 if (pContextRec->ContextFlags & CONTEXT_INTEGER) 427 427 { 428 428 qt_excWriteReg (file, "EAX", pContextRec->ctx_RegEax); … … 434 434 } 435 435 436 if 436 if (pContextRec->ContextFlags & CONTEXT_CONTROL) 437 437 { 438 438 qt_excWriteReg (file, "CS", pContextRec->ctx_SegCs, FALSE); … … 561 561 } 562 562 563 /* !\internal564 565 566 567 */563 /** \internal 564 * Writes module information to the log file. 565 * \a ulOrigin is 1 (self), 2 (imported), or 3 (loaded). Other values are 566 * ignored. 567 */ 568 568 static void qt_excWriteModule (FILE *file, USHORT hmte, char *pszName, 569 569 ULONG ulOrigin = 0) … … 580 580 arc = DosQueryPathInfo (pszName, FIL_STANDARD, &Status, sizeof (Status)); 581 581 582 if ((ulOrigin >= 1 && ulOrigin <= 3) || arc == NO_ERROR 582 if ((ulOrigin >= 1 && ulOrigin <= 3) || arc == NO_ERROR) 583 583 { 584 584 fprintf (file, "\n "); … … 599 599 } 600 600 601 /* !\internal602 603 604 */601 /** \internal 602 * Writes module and all its imports information to the log file. 603 * \a ulOrigin is 1 (self), or 3 (loaded), other values are ignored. 604 */ 605 605 static void qt_excWriteModules (FILE *file, USHORT hmte, QSLREC *pFirstLibRec, 606 606 ULONG ulOrigin) … … 643 643 } WMOS_STATE; 644 644 645 /* !\internal646 647 648 649 */645 /** \internal 646 * Walks the stack and writes information about all encountered modules. 647 * Used only when DosQuerySysState() fails (so qt_excWriteModules() is not 648 * applicable). We use recursiveness to avoid module record duplicates. 649 */ 650 650 static void qt_excWriteModulesOnStack (WMOS_STATE *pState) 651 651 { … … 742 742 } PROCESSINFO; 743 743 744 /* !\internal745 746 */744 /** \internal 745 * Writes exception information to the log file. 746 */ 747 747 static void qt_excWriteException (FILE *file, 748 748 PROCESSINFO *pInfo, … … 868 868 * log file. Note that \a pszFileName must be at least CCHMAXPATH bytes length. 869 869 */ 870 static FILE *qt_excOpenLogFile ( const char *pcszBasePath, char *pszFileName)870 static FILE *qt_excOpenLogFile (const char *pcszBasePath, char *pszFileName) 871 871 { 872 872 FILE *file = NULL; 873 873 874 874 char szFileName[CCHMAXPATH]; 875 char szDir[] = "\\. qt3traps";875 char szDir[] = "\\.systrap"; 876 876 char szFile[] = "\\12345678.123"; 877 877 enum { cbFileName = sizeof(szFileName) }; … … 885 885 char *pszStamp = NULL; 886 886 887 if ( pcszBasePath == NULL || pszFileName == NULL)887 if (pcszBasePath == NULL || pszFileName == NULL) 888 888 return NULL; 889 889 890 if ( access( pcszBasePath, F_OK ) != 0)890 if (access (pcszBasePath, F_OK) != 0) 891 891 return NULL; 892 892 893 if ( strlen( pcszBasePath ) + cbDir + cbFile - 2 >= CCHMAXPATH)893 if (strlen (pcszBasePath) + cbDir + cbFile - 2 >= CCHMAXPATH) 894 894 return NULL; 895 895 896 / / get the full path if it's not 'X:'897 if ( 898 pcszBasePath[1] != ':' 899 { 900 if ( DosQueryPathInfo(pcszBasePath, FIL_QUERYFULLNAME,901 szFileName, cbFileName ) != NO_ERROR)896 /* get the full path if it's not 'X:' */ 897 if (strlen(pcszBasePath) != 2 || 898 pcszBasePath[1] != ':') 899 { 900 if (DosQueryPathInfo (pcszBasePath, FIL_QUERYFULLNAME, 901 szFileName, cbFileName) != NO_ERROR) 902 902 return NULL; 903 903 } 904 904 else 905 strcpy ( szFileName, pcszBasePath);906 907 strcat ( szFileName, szDir);908 if ( access( szFileName, F_OK ) != 0)909 if ( mkdir( szFileName, 0777 ) != 0)905 strcpy (szFileName, pcszBasePath); 906 907 strcat (szFileName, szDir); 908 if (access (szFileName, F_OK) != 0) 909 if (mkdir (szFileName, 0777) != 0) 910 910 return NULL; 911 911 912 cbDirLen = strlen ( szFileName);912 cbDirLen = strlen (szFileName); 913 913 914 / / first, try to use the desired base file name915 916 / /we will append -NN to the file name to add some 'fraction of a917 // second' granularity to avoid name conflicts (0 <= NNN <= 99)918 cbLen = strlen ( pszFileName);919 if ( cbDirLen + cbLen + 8 /* \-NN.xml */ < CCHMAXPATH)920 { 921 strcat ( szFileName, "\\");922 strcat ( szFileName, pszFileName);914 /* first, try to use the desired base file name */ 915 916 /* we will append -NN to the file name to add some 'fraction of a 917 * second' granularity to avoid name conflicts (0 <= NNN <= 99) */ 918 cbLen = strlen (pszFileName); 919 if (cbDirLen + cbLen + 12 /* \-NN.trp.xml */ < CCHMAXPATH) 920 { 921 strcat (szFileName, "\\"); 922 strcat (szFileName, pszFileName); 923 923 cbLen += cbDirLen + 1 /* \ */; 924 for ( ul = 0; ul < 100; ++ul)925 { 926 sprintf ( szFileName + cbLen, "-%02ld.xml", ul);927 if ( access( szFileName, F_OK ) == 0)924 for (ul = 0; ul < 100; ++ul) 925 { 926 sprintf (szFileName + cbLen, "-%02ld.trp.xml", ul); 927 if (access (szFileName, F_OK) == 0) 928 928 continue; 929 file = fopen ( szFileName, "wt");930 if ( file)929 file = fopen (szFileName, "wt"); 930 if (file) 931 931 break; 932 if ( errno == ENAMETOOLONG)932 if (errno == ENAMETOOLONG) 933 933 break; 934 934 } 935 935 } 936 936 937 // next, try a time stamp as a 8x3 file name 938 if ( file == NULL ) 937 /* next, try a time stamp as a 8x3 file name */ 938 939 if (file == NULL) 939 940 { 940 941 pszStamp = szFileName + cbDirLen + 1; 941 strcat ( szFileName, szFile);942 strcat (szFileName, szFile); 942 943 943 ulStamp = time ( NULL);944 945 / /In order to add some 'fraction of a second' granularity to the946 //timestamp, we shift it by 5 bits. This gives us 0x07FFFFFF seconds947 //which is a period of approx. 4,25 years. 5 bits in turn give us 32948 // fractions of a second.944 ulStamp = time (NULL); 945 946 /* In order to add some 'fraction of a second' granularity to the 947 * timestamp, we shift it by 5 bits. This gives us 0x07FFFFFF seconds 948 * which is a period of approx. 4,25 years. 5 bits in turn give us 32 949 * fractions of a second. */ 949 950 ulStamp <<= 5; 950 951 951 / / try some few adajcent stamps if the first one fails952 for ( ul = 0; ul < 32; ++ul, ++ulStamp)953 { 954 sprintf ( pszStamp, "%08lX.xml", ulStamp);955 if ( access( szFileName, F_OK ) == 0)952 /* try some few next stamps if the first one fails */ 953 for (ul = 0; ul < 32; ++ul, ++ulStamp) 954 { 955 sprintf (pszStamp, "%08lX.xml", ulStamp); 956 if (access (szFileName, F_OK) == 0) 956 957 continue; 957 file = fopen ( szFileName, "wt");958 if ( file)958 file = fopen (szFileName, "wt"); 959 if (file) 959 960 break; 960 961 } 961 962 } 962 963 963 if ( file)964 { 965 strncpy ( pszFileName, szFileName, CCHMAXPATH - 1);964 if (file) 965 { 966 strncpy (pszFileName, szFileName, CCHMAXPATH - 1); 966 967 pszFileName[CCHMAXPATH - 1] = '\0'; 967 968 } … … 970 971 } 971 972 972 /* !\internal973 974 */973 /** \internal 974 * Qt Exception handler. 975 */ 975 976 /* static */ 976 977 ULONG APIENTRY 977 QtOS2SysXcptMainHandler::handler (PEXCEPTIONREPORTRECORD pReportRec,978 QtOS2SysXcptMainHandler::handler (PEXCEPTIONREPORTRECORD pReportRec, 978 979 PEXCEPTIONREGISTRATIONRECORD pRegRec, 979 980 PCONTEXTRECORD pContextRec, 980 PVOID pv 981 PVOID pv) 981 982 { 982 983 PROCESSINFO Info = {0}; … … 1073 1074 /* find the base name (w/o path and extension) */ 1074 1075 char *psz = strrchr (szFullExeName, '\\'); 1075 if ( psz)1076 if (psz) 1076 1077 ++ psz; 1077 if ( !psz)1078 if (!psz) 1078 1079 psz = szFullExeName; 1079 1080 strcpy (szBaseExeName, psz); … … 1115 1116 char szBootDrive[] = "\0:"; 1116 1117 ULONG ulBootDrive; 1117 DosQuerySysInfo (QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,1118 &ulBootDrive, sizeof(ulBootDrive) 1118 DosQuerySysInfo (QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, 1119 &ulBootDrive, sizeof(ulBootDrive)); 1119 1120 szBootDrive[0] = (char) ulBootDrive + 'A' - 1; 1120 1121 file = qt_excOpenLogFile (szBootDrive, szFileName);
Note:
See TracChangeset
for help on using the changeset viewer.