Changeset 1332
- Timestamp:
- Dec 12, 2008, 2:06:40 AM (17 years ago)
- Location:
- trunk/dll
- Files:
-
- 2 edited
-
excputil.c (modified) (12 diffs)
-
excputil.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/dll/excputil.c
r1331 r1332 22 22 #define INCL_DOSMISC // DosDumpProcess? 23 23 #define INCL_DOSERRORS // NO_ERROR 24 #include <os2.h>24 // #include <os2.h> 25 25 26 26 #include "wrappers.h" // xmalloc xfree … … 29 29 #include "strutil.h" // GetPString 30 30 31 // #include "excputil.h" // 08 Dec 08 SHL fixme 31 #include "excputil.h" 32 32 33 33 static PSZ pszSrcFile = __FILE__; … … 38 38 } THREADDATA; 39 39 40 _ERR HandleException;41 42 40 /** 43 41 * Wrapper thread that installs exception handler and invokes … … 47 45 static VOID WrapperThread(PVOID pvArgs) 48 46 { 49 EXCEPTIONREGISTRATIONRECORD excpQReg= { NULL, NULL };47 EXCEPTIONREGISTRATIONRECORD regRec = { NULL, NULL }; 50 48 APIRET apiret; 51 49 THREADDATA *ptd = (THREADDATA*)pvArgs; … … 56 54 # endif 57 55 58 excpQReg.ExceptionHandler = HandleException;59 apiret = DosSetExceptionHandler(& excpQReg);56 regRec.ExceptionHandler = HandleException; 57 apiret = DosSetExceptionHandler(®Rec); 60 58 if (apiret != NO_ERROR) { 61 59 Dos_Error(MB_ENTER, apiret, HWND_DESKTOP, pszSrcFile, __LINE__, … … 63 61 } 64 62 63 #if 0 // 11 Dec 08 SHL fixme tobe gone - debug 64 { 65 static UINT when; 66 if (++when == 2) 67 *(char*)0 = 0; 68 } 69 #endif 70 65 71 (*ptd->pfnThread)(ptd->pvArgs); // Invoke thread 66 72 … … 68 74 69 75 if (apiret == NO_ERROR) { 70 apiret = DosUnsetExceptionHandler(& excpQReg);76 apiret = DosUnsetExceptionHandler(®Rec); 71 77 if (apiret != NO_ERROR) { 72 78 Dos_Error(MB_ENTER, apiret, HWND_DESKTOP, pszSrcFile, __LINE__, … … 88 94 89 95 int xbeginthread(VOID (*pfnThread)(PVOID), 90 PVOID unused,91 96 UINT cStackBytes, 92 PVOID pvArgs) 97 PVOID pvArgs, 98 PSZ pszSrcFile, 99 UINT uiLineNumber) 93 100 { 94 101 int rc; … … 98 105 rc = _beginthread(WrapperThread, NULL, cStackBytes, ptd); 99 106 if (rc == -1) 100 Runtime_Error(pszSrcFile, __LINE__,107 Runtime_Error(pszSrcFile, uiLineNumber, 101 108 GetPString(IDS_COULDNTSTARTTHREADTEXT)); 102 109 return rc; … … 120 127 PIB *ppib; 121 128 TIB *ptib; 129 ULONG ulpid; 130 ULONG ultid; 122 131 APIRET apiret; 132 HMODULE hmod; 123 133 124 134 static unsigned working; 125 126 // Report exception in handler only once 135 static PSZ pszExcpMsg = "Caught exception %lx in process %lx (%lu) thread %u at %.24s"; 136 137 // Try to report cascading exceptions in handler only once 138 // This simple test can get confused if multiple threads trap at same time 127 139 if (++working > 1) { 128 140 if (working == 2) { 129 DbgMsg(pszSrcFile, __LINE__, "Caught exception %lx in exception handler at %p",141 DbgMsg(pszSrcFile, __LINE__, "Caught exception %lx at %p while handler active", 130 142 ex, pContext->ctx_RegEip); 131 143 } … … 134 146 } 135 147 148 // Bypass exceptions we don't handle or exceptions we ignore 149 // Keep in sync with exceptq selections since exceptq will ignore anyway 136 150 if ((pReport->fHandlerFlags & (EH_UNWINDING | EH_NESTED_CALL)) || 137 (pReport->ExceptionNum & XCPT_SEVERITY_CODE) != XCPT_FATAL_EXCEPTION) 151 (ex & XCPT_SEVERITY_CODE) != XCPT_FATAL_EXCEPTION || 152 ex == XCPT_ASYNC_PROCESS_TERMINATE || 153 ex == XCPT_PROCESS_TERMINATE || 154 ex == XCPT_UNWIND || 155 ex == XCPT_SIGNAL || 156 ex == XCPT_BREAKPOINT || 157 ex == XCPT_SINGLE_STEP) 138 158 { 139 159 working--; … … 147 167 apiret = DosGetInfoBlocks(&ptib, &ppib); 148 168 if (apiret) { 149 ppib = NULL; 150 ptib = NULL; 151 } 152 153 // 08 Dec 08 SHL fixme to report thread ordinal? 154 DbgMsg(pszSrcFile, __LINE__, "Caught exception %lx in process %lx (%lu) thread %u at %.24s", 155 ex, 156 ppib->pib_ulpid, 157 ppib->pib_ulpid, 158 ptib ? ptib->tib_ptib2->tib2_ultid : 0, 159 pszTime); 160 161 // Check if this is an exception exceptq can handle 162 // Keep in sync with exceptq selections since exceptq will ignore anyway 163 if (ex != XCPT_PROCESS_TERMINATE && 164 ex != XCPT_UNWIND && 165 ex != XCPT_SIGNAL && 166 ex != XCPT_BREAKPOINT && 167 ex != XCPT_SINGLE_STEP && 168 ex != XCPT_ASYNC_PROCESS_TERMINATE) 169 { 170 HMODULE hmod; 171 apiret = DosLoadModule (0, 0, "exceptq" ,&hmod); 172 // Report errors with DbgMsg, Dos_Error unsafe here 173 if (apiret) { 174 if (apiret != ERROR_FILE_NOT_FOUND) 175 DbgMsg(pszSrcFile, __LINE__, "DosLoadModule(exceptq) reported error %u", apiret); 176 } 169 ulpid = 0; 170 ultid = 0; 171 } 172 else { 173 ulpid = ppib->pib_ulpid; 174 ultid = ptib->tib_ptib2->tib2_ultid; 175 } 176 177 DbgMsg(pszSrcFile, __LINE__, pszExcpMsg, 178 ex, ulpid, ulpid, ultid, pszTime); 179 180 // Report errors with DbgMsg, Dos_Error unsafe here 181 apiret = DosLoadModule (0, 0, "exceptq" ,&hmod); 182 if (apiret) { 183 if (apiret != ERROR_FILE_NOT_FOUND) 184 DbgMsg(pszSrcFile, __LINE__, "DosLoadModule(exceptq) reported error %u", apiret); 185 } 186 else { 187 ERR pfn; 188 apiret = DosQueryProcAddr(hmod, 0, "MYHANDLER", (PFN*)&pfn); 189 if (apiret) 190 DbgMsg(pszSrcFile, __LINE__, "DosQueryProcAddr(MYHANDLER) reported error %u", apiret); 177 191 else { 178 ERR pfn; 179 apiret = DosQueryProcAddr(hmod, 0, "MYHANDLER", (PFN*)&pfn); 180 if (apiret) 181 DbgMsg(pszSrcFile, __LINE__, "DosQueryProcAddr(MYHANDLER) reported error %u", apiret); 182 else { 183 // DbgMsg(pszSrcFile, __LINE__, "Invoking exceptq handler at %p", pfn); 184 (*pfn)(pReport, pReg, pContext, pv); 185 handled = TRUE; 186 } 187 DosFreeModule(hmod); 188 } 189 190 // If exceptq not available use local handler 191 if (!handled) { 192 union { 193 struct { 194 ULONG ulEBP; 195 ULONG ulEIP; 196 } stk32; 197 struct { 198 USHORT usBP; 199 USHORT usIP; 200 USHORT usCS; // > 1 and < 0xfff 201 } stk16; 202 } u; 203 ULONG ulObjNum; 204 ULONG ulOffset; 205 ULONG ulEIP; 206 ULONG ulEBP; 207 CHAR szFileName[CCHMAXPATH]; 208 BOOL is32Bit; 209 APIRET apiret; 210 ULONG flags; 211 ULONG cnt; 212 ULONG ulOldEBP = 0; 213 INT c; 214 FILE* fp; 215 192 // DbgMsg(pszSrcFile, __LINE__, "Invoking exceptq handler at %p", pfn); 193 (*pfn)(pReport, pReg, pContext, pv); 216 194 handled = TRUE; 217 218 fp = fopen("fm2_trap.log", "a"); 219 if (!fp) 220 fp = stderr; // Oh well 221 222 if (fp == stderr) 223 fputc('\n', stderr); 224 else { 225 fprintf(fp, "\nCaught exception %lx in process %x (%u) thread %u at %s\n", 226 ex, 227 ppib->pib_ulpid, 228 ppib->pib_ulpid, 229 ptib ? ptib->tib_ptib2->tib2_ultid : 0, 230 pszTime); 231 } 232 233 // fixme to do 16 bit better, 5b = FLAT_CS 234 if (pContext->ctx_SegCs == 0x5b) { 235 is32Bit = TRUE; // Assume 32-bit 236 u.stk32.ulEIP = pContext->ctx_RegEip; 237 u.stk32.ulEBP = pContext->ctx_RegEbp; 195 } 196 DosFreeModule(hmod); 197 } 198 199 // If exceptq not available use local handler 200 if (!handled) { 201 union { 202 struct { 203 ULONG ulEBP; 204 ULONG ulEIP; 205 } stk32; 206 struct { 207 USHORT usBP; 208 USHORT usIP; 209 USHORT usCS; // > 1 and < 0xfff 210 } stk16; 211 } u; 212 ULONG ulObjNum; 213 ULONG ulOffset; 214 ULONG ulEIP; 215 ULONG ulEBP; 216 CHAR szFileName[CCHMAXPATH]; 217 BOOL is32Bit; 218 APIRET apiret; 219 ULONG flags; 220 ULONG cnt; 221 ULONG ulOldEBP = 0; 222 INT c; 223 FILE* fp; 224 225 handled = TRUE; 226 227 // Write stack trace to log file - let kernel do popuplog.os2 228 fp = fopen("fm2_trap.log", "a"); 229 if (!fp) 230 fp = stderr; // Oh well 231 232 if (fp != stderr) { 233 fputc('\n', fp); 234 fprintf(fp, pszExcpMsg, 235 ex, ulpid, ulpid, ultid, pszTime); 236 fputc('\n', stderr); 237 } 238 fputc('\n', stderr); 239 240 // fixme to support mixed 32-bit/16-bit stacks, 5b = FLAT_CS 241 if (pContext->ctx_SegCs == 0x5b) { 242 is32Bit = TRUE; // Assume 32-bit 243 u.stk32.ulEIP = pContext->ctx_RegEip; 244 u.stk32.ulEBP = pContext->ctx_RegEbp; 245 } 246 else { 247 is32Bit = FALSE; 248 u.stk16.usIP = pContext->ctx_RegEip; 249 u.stk16.usBP = pContext->ctx_RegEbp; 250 } 251 252 // Walk stack frames 253 for (c = 0; c < 100; c++) { 254 if (is32Bit) { 255 ulEIP = u.stk32.ulEIP; 256 ulEBP = u.stk32.ulEBP; 238 257 } 239 258 else { 240 is32Bit = FALSE; 241 u.stk16.usIP = pContext->ctx_RegEip; 242 u.stk16.usBP = pContext->ctx_RegEbp; 259 ulEIP = ((ULONG) (pContext->ctx_SegCs & ~7) << 13) | u.stk16.usIP; 260 ulEBP = ((ULONG) (pContext->ctx_SegSs & ~7) << 13) | u.stk16.usBP; 243 261 } 244 262 245 // Walk stack 246 for (c = 0; c < 100; c++) { 247 if (is32Bit) { 248 ulEIP = u.stk32.ulEIP; 249 ulEBP = u.stk32.ulEBP; 250 } 251 else { 252 ulEIP = ((ULONG) (pContext->ctx_SegCs & ~7) << 13) | u.stk16.usIP; 253 ulEBP = ((ULONG) (pContext->ctx_SegSs & ~7) << 13) | u.stk16.usBP; 254 } 255 256 apiret = DosQueryModFromEIP(&hmod, &ulObjNum, CCHMAXPATH, szFileName, 257 &ulOffset, ulEIP); 258 if (apiret) { 259 ulObjNum = 0; 260 ulOffset = 0; 261 strcpy(szFileName, "n/a"); 262 } 263 else 264 ulObjNum++; // Number from 1..n for display 265 266 fprintf(fp, " Stack frame %u @ %lx:%lx %s %lx:%lx\n", 267 c, 268 pContext->ctx_SegCs, ulEIP, 269 szFileName, ulObjNum, ulOffset); 270 271 if (apiret) 272 break; 273 274 if (!ulEBP || ulEBP <= ulOldEBP) 275 break; 276 277 cnt = sizeof(u); 278 279 apiret = DosQueryMem((void*)ulEBP, &cnt, &flags); 280 if (apiret || (flags & (PAG_COMMIT | PAG_READ)) != (PAG_COMMIT | PAG_READ)) 281 break; // We are lost 282 283 ulOldEBP = ulEBP; 284 memcpy((void*)&u, (void*)ulEBP, sizeof(u)); 285 286 } // for 287 288 if (fp && fp != stderr) 289 fclose(fp); 290 291 } // if !handled 292 293 // DbgMsg(pszSrcFile, __LINE__, "We are going to die now"); 294 295 } // if can handle here 263 apiret = DosQueryModFromEIP(&hmod, &ulObjNum, CCHMAXPATH, szFileName, 264 &ulOffset, ulEIP); 265 if (apiret) { 266 ulObjNum = 0; 267 ulOffset = 0; 268 strcpy(szFileName, "n/a"); 269 } 270 else 271 ulObjNum++; // Number from 1..n for display 272 273 fprintf(fp, " Stack frame %u @ %lx:%lx %s %lx:%lx\n", 274 c, 275 pContext->ctx_SegCs, ulEIP, 276 szFileName, ulObjNum, ulOffset); 277 278 if (apiret) 279 break; 280 281 if (!ulEBP || ulEBP <= ulOldEBP) 282 break; 283 284 cnt = sizeof(u); 285 286 apiret = DosQueryMem((void*)ulEBP, &cnt, &flags); 287 if (apiret || (flags & (PAG_COMMIT | PAG_READ)) != (PAG_COMMIT | PAG_READ)) 288 break; // We are lost 289 290 ulOldEBP = ulEBP; 291 memcpy((void*)&u, (void*)ulEBP, sizeof(u)); 292 293 } // for 294 295 if (fp || fp != stderr) 296 fclose(fp); 297 298 } // if !handled 299 300 // DbgMsg(pszSrcFile, __LINE__, "We are going to die now"); 296 301 297 302 working--; -
trunk/dll/excputil.h
r1331 r1332 13 13 14 14 #if !defined(OS2_INCLUDED) 15 #define INCL_DOSEXCEPTIONS // XCTP_... 15 16 #include <os2.h> 16 17 #endif 17 18 18 19 int xbeginthread(VOID (*pfnThread)(PVOID), 19 PVOID unused,20 20 UINT cStackBytes, 21 PVOID pvArgs); 21 PVOID pvArgs, 22 PSZ pszSrcFile, 23 UINT uiLineNumber); 24 25 _ERR HandleException; 22 26 23 27 #endif // EXCPUTIL_H
Note:
See TracChangeset
for help on using the changeset viewer.
