Changeset 21662 for trunk/src/kernel32/exceptions.cpp
- Timestamp:
- Jul 5, 2011, 7:52:42 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/exceptions.cpp
r21647 r21662 462 462 { 463 463 PWINEXCEPTION_FRAME frame, prevFrame, dispatch; 464 WINEXCEPTION_RECORD record , newrec;464 WINEXCEPTION_RECORD record; //, newrec; 465 465 WINCONTEXT context; 466 466 DWORD rc; … … 471 471 if (!winteb) 472 472 { 473 /* We're being called from __seh_handler called upon unwinding the OS/2 474 * exception chain after the Win32 TIB structure is destroyed. This for 475 * example happens when we terminate the thread or the process from within 476 * the __try block. Just ignore this call retur (note that the Win32 477 * exception chain should be already unwound by this moment). */ 478 dprintf(("KERNEL32: RtlUnwind returning due to zero Win32 TEB.\n")); 473 dprintf(("KERNEL32: RtlUnwind TEB is NULL\n")); 474 DebugInt3(); 479 475 return 0; 480 476 } … … 526 522 if (pEndFrame && (frame > pEndFrame)) 527 523 { 524 #if 0 525 // TODO 528 526 newrec.ExceptionCode = STATUS_INVALID_UNWIND_TARGET; 529 527 newrec.ExceptionFlags = EH_NONCONTINUABLE; 530 528 newrec.ExceptionRecord = pRecord; 531 529 newrec.NumberParameters = 0; 530 RtlRaiseException(&newrec, NULL); 531 #else 532 532 dprintf(("KERNEL32: RtlUnwind terminating thread (invalid target).\n")); 533 533 DosExit(EXIT_THREAD, 0); 534 #endif 534 535 } 535 536 if (((void*)frame < winteb->stack_low) || … … 537 538 (int)frame & 3) 538 539 { 540 #if 0 541 // TODO 539 542 newrec.ExceptionCode = STATUS_BAD_STACK; 540 543 newrec.ExceptionFlags = EH_NONCONTINUABLE; 541 544 newrec.ExceptionRecord = pRecord; 542 545 newrec.NumberParameters = 0; 546 #else 543 547 dprintf(("KERNEL32: RtlUnwind terminating thread (bad stack).\n")); 544 548 DosExit(EXIT_THREAD, 0); 549 #endif 545 550 } 546 551 … … 548 553 dprintf(("KERNEL32: RtlUnwind - calling exception handler %08X", frame->Handler)); 549 554 if(frame->Handler) { 555 // ensure the Win32 FS (may be accessed directly in the handler) 556 DWORD oldsel = SetReturnFS(winteb->teb_sel); 550 557 rc = EXC_CallHandler(pRecord, frame, &context, &dispatch, frame->Handler, EXC_UnwindHandler ); 558 // restore FS 559 SetFS(oldsel); 551 560 } 552 561 else { … … 563 572 break; 564 573 default: 574 #if 0 575 // TODO 565 576 newrec.ExceptionCode = STATUS_INVALID_DISPOSITION; 566 577 newrec.ExceptionFlags = EH_NONCONTINUABLE; 567 578 newrec.ExceptionRecord = pRecord; 568 579 newrec.NumberParameters = 0; 569 dprintf(("KERNEL32: RtlUnwind terminating thread.\n")); 580 #else 581 dprintf(("KERNEL32: RtlUnwind terminating thread (invalid disposition).\n")); 570 582 DosExit(EXIT_THREAD, 0); 583 #endif 571 584 break; 572 585 } 573 586 dprintf(("KERNEL32: RtlUnwind (before)- frame=%08X, frame->Prev=%08X", frame, prevFrame)); 574 SetExceptionChain((DWORD)prevFrame);587 winteb->except = (void*)prevFrame; 575 588 frame = prevFrame; 576 589 dprintf(("KERNEL32: RtlUnwind (after) - frame=%08X, frame->Prev=%08X", frame, … … 1209 1222 #endif 1210 1223 1224 // borrowed from ntddk.h 1225 extern "C" 1226 void WIN32API RtlUnwind( 1227 LPVOID, 1228 LPVOID, 1229 LPVOID,DWORD); 1230 1211 1231 // Assembly wrapper for clearing the direction flag before calling our real 1212 1232 // exception handler … … 1234 1254 // sprintfException(pERepRec, pERegRec, pCtxRec, p, szTrapDump); 1235 1255 // } 1256 1257 // We have to disable unwinding of the Win32 exception handlers because 1258 // experiments have shown that when running under SMP kernel the stack 1259 // becomes corrupt at the time when unwinding takes place: attempts to 1260 // to follow the exception chain crash when accessing one of the the 1261 // previous frame. Although it may seem that performing unwinding here 1262 // (when we are definitely above any Win32 exception frames installed by 1263 // the application so that the OS could theoretically already discard lower 1264 // stack areas) is wrong, it's not the case of the crash. First, doing the 1265 // very same thing from the SEH handler (see comments in sehutil.s), i.e. 1266 // when the given Win32 stack frame (and all previous ones) is definitely 1267 // alive, crahes due to the same stack corruption too. Second, when running 1268 // under UNI kernel, BOTH approaches don't crash (i.e. the stack is fine). 1269 // This looks like the SMP kernel doesn't manage the stack right during 1270 // exception handling :( See also http://svn.netlabs.org/odin32/ticket/37. 1271 // 1272 // Note that disabling unwinding also breaks support for performing 1273 // setjmp()/lonjmp() that crosses the bounds of the __try {} block. 1274 #if 0 1275 if (pERepRec->fHandlerFlags & EH_UNWINDING) 1276 { 1277 // unwind the appropriate portion of the Win32 exception chain 1278 if (pERepRec->fHandlerFlags & EH_EXIT_UNWIND) 1279 { 1280 dprintf(("KERNEL32: OS2ExceptionHandler: EH_EXIT_UNWIND, " 1281 "unwinding all the Win32 exception chain")); 1282 RtlUnwind(NULL, 0, 0, 0); 1283 } 1284 else 1285 { 1286 dprintf(("KERNEL32: OS2ExceptionHandler: EH_UNWINDING, " 1287 "unwinding the Win32 exception chain up to 0x%p", pERegRec)); 1288 1289 // find a Win32 exception frame closest to the OS/2 one (pERegRec) 1290 // and unwind up to the previous one (to unwind the closest frame 1291 // itself too as we are definitely jumping out of it) 1292 TEB *winteb = GetThreadTEB(); 1293 PWINEXCEPTION_FRAME frame = (PWINEXCEPTION_FRAME)winteb->except; 1294 while (frame != NULL && ((ULONG)frame)!= 0xFFFFFFFF && 1295 ((ULONG)frame) <= ((ULONG)pERegRec)) 1296 frame = __seh_get_prev_frame(frame); 1297 if (((ULONG)frame) == 0xFFFFFFFF) 1298 frame = NULL; 1299 1300 RtlUnwind(frame, 0, 0, 0); 1301 } 1302 goto continuesearch; 1303 } 1304 #endif 1236 1305 1237 1306 /* Access violation at a known location */ … … 1517 1586 if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p) == TRUE) 1518 1587 { 1588 dprintf(("KERNEL32: OS2ExceptionHandler: fix and continue\n")); 1519 1589 goto continueexecution; 1520 1590 } 1521 1591 else 1522 1592 { 1593 dprintf(("KERNEL32: OS2ExceptionHandler: continue search\n")); 1523 1594 goto continuesearch; 1524 1595 }
Note:
See TracChangeset
for help on using the changeset viewer.