source: trunk/src/kernel32/exceptions.cpp@ 46

Last change on this file since 46 was 46, checked in by sandervl, 26 years ago

* empty log message *

File size: 25.0 KB
Line 
1/*
2 * Win32 Device IOCTL API functions for OS/2
3 *
4 * Ported Wine exception handling code
5 *
6 * Copyright 1998 Sander van Leeuwen (OS/2 port)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 *
12 * (win32\except.c)
13 *
14 * Win32 exception functions
15 *
16 * Copyright (c) 1996 Onno Hovers, (onno@stack.urc.tue.nl)
17 *
18 * Notes:
19 * What really happens behind the scenes of those new
20 * __try{...}__except(..){....} and
21 * __try{...}__finally{...}
22 * statements is simply not documented by Microsoft. There could be different
23 * reasons for this:
24 * One reason could be that they try to hide the fact that exception
25 * handling in Win32 looks almost the same as in OS/2 2.x.
26 * Another reason could be that Microsoft does not want others to write
27 * binary compatible implementations of the Win32 API (like us).
28 *
29 * Whatever the reason, THIS SUCKS!! Ensuring portabilty or future
30 * compatability may be valid reasons to keep some things undocumented.
31 * But exception handling is so basic to Win32 that it should be
32 * documented!
33 *
34 * Fixmes:
35 * -Most functions need better parameter checking.
36 * -I do not know how to handle exceptions within an exception handler.
37 * or what is done when ExceptionNestedException is returned from an
38 * exception handler
39 * -Real exceptions are not yet implemented. only the exception functions
40 * are implemented. A real implementation needs some new code in
41 * loader/signal.c. There would also be a need for showing debugging
42 * information in UnhandledExceptionFilter.
43 *
44 */
45#define INCL_BASE
46#include <os2.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <assert.h>
50#include <string.h>
51#include <builtin.h>
52#include "exceptions.h"
53#include "except.h"
54#include "misc.h"
55
56//Global Process Unhandled exception filter
57static LPTOP_LEVEL_EXCEPTION_FILTER CurrentUnhExceptionFlt = NULL;
58static UINT CurrentErrorMode = 0;
59static PEXCEPTION_HANDLER StartupCodeHandler = NULL;
60
61extern "C" PWINEXCEPTION_FRAME QueryExceptionChain();
62extern "C" PWINEXCEPTION_FRAME GetExceptionRecord(ULONG offset, ULONG segment);
63
64LONG WIN32API UnhandledExceptionFilter(PWINEXCEPTION_POINTERS lpexpExceptionInfo);
65
66//******************************************************************************
67//******************************************************************************
68UINT WIN32API SetErrorMode(UINT fuErrorMode)
69{
70 UINT oldmode = CurrentErrorMode;
71
72 dprintf(("OS2SetErrorMode to %d\n", fuErrorMode));
73 CurrentErrorMode = fuErrorMode;
74
75 return(oldmode);
76}
77//******************************************************************************
78//Unwinds exception handlers (heavily influenced by Wine)
79//******************************************************************************
80VOID _Pascal OS2RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags,
81 DWORD cArguments, DWORD *lpArguments,
82 DWORD eip, DWORD esp, DWORD ebp, DWORD flags,
83 DWORD eax, DWORD ebx, DWORD ecx, DWORD edx,
84 DWORD edi, DWORD esi, DWORD cs, DWORD ds,
85 DWORD es, DWORD fs, DWORD gs, DWORD ss)
86{
87 PWINEXCEPTION_FRAME pframe;
88 WINEXCEPTION_RECORD record;
89 WINEXCEPTION_POINTERS ExceptionInfo;
90 WINCONTEXT context;
91 DWORD dispatch;
92 int rc;
93 int i;
94
95 dprintf(("RaiseException %d\n", dwExceptionCode));
96
97 /* compose an exception record */
98 record.ExceptionCode = dwExceptionCode;
99 record.ExceptionFlags = dwExceptionFlags;
100 record.ExceptionRecord = NULL;
101 record.NumberParameters = cArguments;
102 record.ExceptionAddress = (LPVOID)eip;
103
104 memset(&context, 0, sizeof(context));
105 context.ContextFlags = WINCONTEXT_FULL; //segments, integer, control
106 context.SegGs = gs;
107 context.SegFs = fs;
108 context.SegEs = es;
109 context.SegDs = ds;
110 context.Edi = edi;
111 context.Esi = esi;
112 context.Ebx = ebx;
113 context.Edx = edx;
114 context.Ecx = ecx;
115 context.Eax = eax;
116 context.Ebp = ebp;
117 context.Eip = eip;
118 context.SegCs = cs;
119 context.EFlags = flags;
120 context.Esp = esp;
121 context.SegSs = ss;
122
123 if(lpArguments) {
124 for(i=0;i<cArguments;i++)
125 record.ExceptionInformation[i] = lpArguments[i];
126 }
127
128 // get chain of exception frames
129 rc = ExceptionContinueSearch;
130 pframe = QueryExceptionChain();
131 while( (pframe != NULL) && (pframe != ((void *)0xFFFFFFFF)) ) {
132 dispatch=0;
133 rc = pframe->Handler(&record, pframe, &context, &dispatch);
134
135 if(rc == ExceptionContinueExecution)
136 break;
137
138 pframe = pframe->Prev;
139 }
140 if(rc == ExceptionContinueSearch && UnhandledExceptionFilter != NULL) {
141 ExceptionInfo.ExceptionRecord = &record;
142 ExceptionInfo.ContextRecord = &context;
143
144 rc = UnhandledExceptionFilter(&ExceptionInfo);
145 }
146
147 if(rc != ExceptionContinueExecution)
148 {
149 DosExit(EXIT_PROCESS, 0);
150 }
151 return;
152}
153//******************************************************************************
154//Unwinds exception handlers (heavily influenced by Wine)
155//******************************************************************************
156int _Pascal OS2RtlUnwind(PWINEXCEPTION_FRAME pEndFrame, LPVOID unusedEip,
157 PWINEXCEPTION_RECORD pRecord, DWORD returnEax,
158 DWORD eip, DWORD esp, DWORD ebp, DWORD flags,
159 DWORD eax, DWORD ebx, DWORD ecx, DWORD edx,
160 DWORD edi, DWORD esi, DWORD cs, DWORD ds,
161 DWORD es, DWORD fs, DWORD gs, DWORD ss)
162{
163 WINEXCEPTION_RECORD record;
164 WINCONTEXT context;
165 DWORD dispatch;
166 int rc;
167
168 dprintf(("RtlUnwind\n"));
169
170 memset(&context, 0, sizeof(context));
171 context.ContextFlags = WINCONTEXT_FULL; //segments, integer, control
172 context.SegGs = gs;
173 context.SegFs = fs;
174 context.SegEs = es;
175 context.SegDs = ds;
176 context.Edi = edi;
177 context.Esi = esi;
178 context.Ebx = ebx;
179 context.Edx = edx;
180 context.Ecx = ecx;
181 context.Eax = returnEax;
182 context.Ebp = ebp;
183 context.Eip = eip;
184 context.SegCs = cs;
185 context.EFlags = flags;
186 context.Esp = esp;
187 context.SegSs = ss;
188
189 /* build an exception record, if we do not have one */
190 if(!pRecord) {
191 record.ExceptionCode = STATUS_INVALID_DISPOSITION;
192 record.ExceptionFlags = 0;
193 record.ExceptionRecord = NULL;
194 record.ExceptionAddress = (LPVOID)eip;
195 record.NumberParameters = 0;
196 pRecord = &record;
197 }
198
199 if(pEndFrame)
200 pRecord->ExceptionFlags |= EH_UNWINDING;
201 else pRecord->ExceptionFlags |= EH_UNWINDING | EH_EXIT_UNWIND;
202
203 /* get chain of exception frames */
204 while((QueryExceptionChain() != NULL) && (QueryExceptionChain() != (void *)0xffffffff) &&
205 (QueryExceptionChain() != pEndFrame)) {
206 dispatch=0;
207 rc = QueryExceptionChain()->Handler(pRecord,
208 QueryExceptionChain(),
209 &context, &dispatch);
210
211 if((rc == ExceptionCollidedUnwind) && (QueryExceptionChain() != (LPVOID)dispatch)) {
212 SetExceptionChain(dispatch);
213 }
214 else
215 if((QueryExceptionChain() != pEndFrame) && (QueryExceptionChain() != QueryExceptionChain()->Prev))
216 SetExceptionChain((DWORD)QueryExceptionChain()->Prev);
217 else break;
218 }
219 if(pEndFrame == UNWIND_ALL) {
220 DosExit(EXIT_THREAD, 0);
221 }
222 return(0);
223}
224//******************************************************************************
225//******************************************************************************
226LONG WIN32API UnhandledExceptionFilter(PWINEXCEPTION_POINTERS lpexpExceptionInfo)
227{
228 char message[72];
229 DWORD rc;
230
231 dprintf(("UnhandledExceptionFilter\n"));
232
233 if(CurrentUnhExceptionFlt && !(CurrentErrorMode & (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX))) {
234 rc = CurrentUnhExceptionFlt(lpexpExceptionInfo);
235 if(rc != WINEXCEPTION_CONTINUE_SEARCH)
236 return rc;
237 }
238
239 sprintf(message, "Unhandled exception 0x%08lx at address 0x%08lx.",
240 lpexpExceptionInfo->ExceptionRecord->ExceptionCode,
241 lpexpExceptionInfo->ExceptionRecord->ExceptionAddress);
242
243 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, message, "Oh, nooo!", 0, MB_OK | MB_ERROR);
244 return WINEXCEPTION_EXECUTE_HANDLER;
245}
246//******************************************************************************
247//******************************************************************************
248LPTOP_LEVEL_EXCEPTION_FILTER WIN32API SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
249{
250 LPTOP_LEVEL_EXCEPTION_FILTER old = CurrentUnhExceptionFlt;
251 dprintf(("SetUnhandledExceptionFilter to %X\n", lpTopLevelExceptionFilter));
252
253 CurrentUnhExceptionFlt = lpTopLevelExceptionFilter;
254
255 return(old);
256}
257//******************************************************************************
258extern "C" ULONG getEAX();
259extern "C" ULONG getEBX();
260//******************************************************************************
261void KillWin32Process(void)
262{
263 char excptmsg[64];
264 ULONG excptaddr, excptnr;
265
266 excptnr = getEAX();
267 excptaddr = getEBX();
268
269 dprintf(("KillWin32Process: Do you feel lucky, punk?!\n"));
270// sprintf(excptmsg, "Fatal Exception %X at %X", excptnr, excptaddr);
271// WinMessageBox(HWND_DESKTOP, NULL, excptmsg, "Win32 for OS/2", 0, MB_ERROR | MB_OK);
272 SetExceptionChain((ULONG)0);
273 DosExit(EXIT_PROCESS, 666);
274}
275//******************************************************************************
276APIRET APIENTRY DosQueryModFromEIP (PULONG pulModule,
277 PULONG pulObject,
278 ULONG ulBufferLength,
279 PSZ pszBuffer,
280 PULONG pulOffset,
281 ULONG ulEIP);
282//******************************************************************************
283void dprintfException(PEXCEPTIONREPORTRECORD pERepRec,
284 PEXCEPTIONREGISTRATIONRECORD pERegRec,
285 PCONTEXTRECORD pCtxRec,
286 PVOID p)
287{
288 PSZ pszExceptionName = "<unknown>"; /* points to name/type excpt */
289 char szData[128]; /* local storage for excpt dep. information */
290 char szData2[128]; /* local storage for excpt dep. information */
291 APIRET rc = XCPT_CONTINUE_SEARCH; /* excpt-dep. code */
292 BOOL fExcptSoftware = FALSE; /* software/hardware gen. exceptn */
293 BOOL fExcptFatal = TRUE; /* fatal exception ? */
294 BOOL fExcptPortable = TRUE; /* portability of exception */
295 PPIB pPIB; /* process information block */
296 PTIB pTIB; /* thread information block */
297 ULONG ulModule; /* module number */
298 ULONG ulObject; /* object number within the module */
299 CHAR szModule[260]; /* buffer for the module name */
300 ULONG ulOffset; /* offset within the object within the module */
301
302 szData[0] = 0; /* initialize */
303 szData2[0] = 0; /* initialize */
304 switch(pERepRec->ExceptionNum) /* take according action */
305 {
306 /* portable, non-fatal software-generated exceptions */
307 case XCPT_GUARD_PAGE_VIOLATION:
308 pszExceptionName = "Guard Page Violation";
309 sprintf(szData,
310 "R/W %08x at %08x.",
311 pERepRec->ExceptionInfo[0],
312 pERepRec->ExceptionInfo[1]);
313 fExcptSoftware = TRUE;
314 fExcptFatal = FALSE;
315 rc = XCPT_CONTINUE_EXECUTION;
316 break;
317
318 case XCPT_UNABLE_TO_GROW_STACK:
319 pszExceptionName = "Unable To Grow Stack";
320 fExcptSoftware = TRUE;
321 fExcptFatal = FALSE;
322 rc = XCPT_CONTINUE_EXECUTION;
323 break;
324
325 /* portable, fatal, hardware-generated exceptions */
326 case XCPT_ACCESS_VIOLATION:
327 pszExceptionName = "Access Violation";
328 /* sprintf (szData, "Access type %08x at %08x.", pERepRec->ExceptionInfo[0],
329 pERepRec->ExceptionInfo[1]); */
330 switch (pERepRec->ExceptionInfo[0])
331 {
332 case XCPT_READ_ACCESS:
333 sprintf (szData,
334 "Read Access at address %08x",
335 pERepRec->ExceptionInfo[1]);
336 break;
337
338 case XCPT_WRITE_ACCESS:
339 sprintf (szData,
340 "Write Access at address %08x",
341 pERepRec->ExceptionInfo[1]);
342 break;
343
344 case XCPT_SPACE_ACCESS:
345 sprintf (szData,
346 "Space Access at selector %08x",
347 pERepRec->ExceptionInfo[1]);
348 break;
349
350 case XCPT_LIMIT_ACCESS:
351 strcpy (szData,
352 "Limit Access");
353 break;
354
355 case XCPT_UNKNOWN_ACCESS:
356 strcpy (szData,
357 "Unknown Access");
358 break;
359
360 default:
361 strcpy (szData,
362 "(Invalid Access Code)");
363 break;
364 }
365 break;
366
367 case XCPT_INTEGER_DIVIDE_BY_ZERO:
368 pszExceptionName = "Division By Zero (Integer)";
369 break;
370
371 case XCPT_FLOAT_DIVIDE_BY_ZERO:
372 pszExceptionName = "Division By Zero (Float)";
373 break;
374
375 case XCPT_FLOAT_INVALID_OPERATION:
376 pszExceptionName = "Invalid Floating Point Operation";
377 break;
378
379 case XCPT_ILLEGAL_INSTRUCTION:
380 pszExceptionName = "Illegal Instruction";
381 break;
382
383 case XCPT_PRIVILEGED_INSTRUCTION:
384 pszExceptionName = "Privileged Instruction";
385 break;
386
387 case XCPT_INTEGER_OVERFLOW:
388 pszExceptionName = "Integer Overflow";
389 break;
390
391 case XCPT_FLOAT_OVERFLOW:
392 pszExceptionName = "Floating Point Overflow";
393 break;
394
395 case XCPT_FLOAT_UNDERFLOW:
396 pszExceptionName = "Floating Point Underflow";
397 break;
398
399 case XCPT_FLOAT_DENORMAL_OPERAND:
400 pszExceptionName = "Floating Point Denormal Operand";
401 break;
402
403 case XCPT_FLOAT_INEXACT_RESULT:
404 pszExceptionName = "Floating Point Inexact Result";
405 break;
406
407 case XCPT_FLOAT_STACK_CHECK:
408 pszExceptionName = "Floating Point Stack Check";
409 break;
410
411 case XCPT_DATATYPE_MISALIGNMENT:
412 pszExceptionName = "Datatype Misalignment";
413 sprintf(szData,
414 "R/W %08x alignment %08x at %08x.",
415 pERepRec->ExceptionInfo[0],
416 pERepRec->ExceptionInfo[1],
417 pERepRec->ExceptionInfo[2]);
418 break;
419
420 case XCPT_BREAKPOINT:
421 pszExceptionName = "Breakpoint (don't debug me! :)";
422 break;
423
424 case XCPT_SINGLE_STEP:
425 pszExceptionName = "Single Step (don't debug me! :)";
426 break;
427
428 /* portable, fatal, software-generated exceptions */
429 case XCPT_IN_PAGE_ERROR:
430 pszExceptionName = "In Page Error";
431 sprintf(szData,
432 "at %08x.",
433 pERepRec->ExceptionInfo[0]);
434 fExcptSoftware = TRUE;
435 break;
436
437 case XCPT_PROCESS_TERMINATE:
438 pszExceptionName = "Process Termination";
439 fExcptSoftware = TRUE;
440 break;
441
442 case XCPT_ASYNC_PROCESS_TERMINATE:
443 pszExceptionName = "Process Termination (async)";
444 sprintf(szData,
445 "terminating thread TID=%u",
446 pERepRec->ExceptionInfo[0]);
447 fExcptSoftware = TRUE;
448 break;
449
450 case XCPT_NONCONTINUABLE_EXCEPTION:
451 pszExceptionName = "Noncontinuable Exception";
452 fExcptSoftware = TRUE;
453 break;
454
455 case XCPT_INVALID_DISPOSITION:
456 pszExceptionName = "Invalid Disposition";
457 fExcptSoftware = TRUE;
458 break;
459
460 /* non-portable, fatal exceptions */
461 case XCPT_INVALID_LOCK_SEQUENCE:
462 pszExceptionName = "Invalid Lock Sequence";
463 fExcptSoftware = TRUE;
464 fExcptPortable = FALSE;
465 break;
466
467 case XCPT_ARRAY_BOUNDS_EXCEEDED:
468 pszExceptionName = "Array Bounds Exceeded";
469 fExcptSoftware = TRUE;
470 fExcptPortable = FALSE;
471 break;
472
473 /* unwind operation exceptions */
474 case XCPT_UNWIND:
475 pszExceptionName = "Unwind Exception";
476 fExcptSoftware = TRUE;
477 fExcptPortable = FALSE;
478 break;
479
480 case XCPT_BAD_STACK:
481 pszExceptionName = "Unwind Exception, Bad Stack";
482 fExcptSoftware = TRUE;
483 fExcptPortable = FALSE;
484 break;
485
486 case XCPT_INVALID_UNWIND_TARGET:
487 pszExceptionName = "Unwind Exception, Invalid Target";
488 fExcptSoftware = TRUE;
489 fExcptPortable = FALSE;
490 break;
491
492 /* fatal signal exceptions */
493 case XCPT_SIGNAL:
494 pszExceptionName = "Signal";
495 sprintf(szData,
496 "Signal Number = %08x",
497 pERepRec->ExceptionInfo[0]);
498 fExcptSoftware = TRUE;
499 fExcptPortable = FALSE;
500
501 switch (pERepRec->ExceptionInfo[0]) /* resolve signal information */
502 {
503 case XCPT_SIGNAL_INTR:
504 pszExceptionName = "Signal (Interrupt)";
505 break;
506
507 case XCPT_SIGNAL_KILLPROC:
508 pszExceptionName = "Signal (Kill Process)";
509 break;
510
511 case XCPT_SIGNAL_BREAK:
512 pszExceptionName = "Signal (Break)";
513 break;
514 }
515 break;
516
517 default:
518 pszExceptionName = "(unknown exception code)";
519 sprintf(szData,
520 "Exception Code = %08x",
521 pERepRec->ExceptionNum);
522 }
523
524
525 /* now dump the information to the logfile */
526 dprintf(("---[Exception Information]------------\n"));
527 sprintf(szData2,
528 " %s (",
529 pszExceptionName);
530
531 if (fExcptSoftware == TRUE) /* software or hardware generated ? */
532 strcat (szData2, "software generated,");
533 else
534 strcat (szData2, "hardware generated,");
535
536 if (fExcptPortable == TRUE) /* portable exception ? */
537 strcat (szData2, "portable,");
538 else
539 strcat (szData2, "non-portable,");
540
541 if (fExcptFatal == TRUE) /* fatal exception ? */
542 strcat (szData2, "fatal");
543 else
544 strcat (szData2, "non-fatal");
545
546 strcat (szData2, /* add trailing brace */
547 ")\n");
548
549
550 dprintf((szData2));
551
552 if (szData[0] != 0) /* see if there is an additional entry */
553 dprintf((" %s\n",
554 szData));
555
556 rc = DosQueryModFromEIP(&ulModule,
557 &ulObject,
558 sizeof(szModule),
559 szModule,
560 &ulOffset,
561 (ULONG)pERepRec->ExceptionAddress);
562
563 dprintf((" Exception Address = %08x ",
564 pERepRec->ExceptionAddress));
565
566 if (rc == NO_ERROR)
567 dprintf(("%s (#%u), Obj #%u, Offset %08x\n",
568 szModule,
569 ulModule,
570 ulObject,
571 ulOffset));
572 else
573 dprintf(("\n"));
574
575
576 rc = DosGetInfoBlocks (&pTIB, /* query kernel information blocks */
577 &pPIB);
578 if (rc == NO_ERROR)
579 {
580 dprintf((" Thread: Ordinal TID: %u, TID: %u, Priority: %04xh\n",
581 pTIB->tib_ordinal,
582 pTIB->tib_ptib2->tib2_ultid,
583 pTIB->tib_ptib2->tib2_ulpri));
584
585 dprintf((" Process: PID: %u, Parent: %u, Status: %u\n",
586 pPIB->pib_ulpid,
587 pPIB->pib_ulppid,
588 pPIB->pib_flstatus));
589 }
590
591 if (pCtxRec->ContextFlags & CONTEXT_CONTROL) /* check flags */
592dprintf((" SS:ESP=%04x:%08x EFLAGS=%08x\n"
593 " CS:EIP=%04x:%08x EBP =%08x\n",
594 pCtxRec->ctx_SegSs,
595 pCtxRec->ctx_RegEsp,
596 pCtxRec->ctx_EFlags,
597 pCtxRec->ctx_SegCs,
598 pCtxRec->ctx_RegEip,
599 pCtxRec->ctx_RegEbp));
600
601 if (pCtxRec->ContextFlags & CONTEXT_INTEGER) /* check flags */
602 dprintf((" EAX=%08x ESI=%08x\n"
603 " EBX=%08x EDI=%08x\n"
604 " ECX=%08x\n"
605 " EDX=%08x\n",
606 pCtxRec->ctx_RegEax,
607 pCtxRec->ctx_RegEsi,
608 pCtxRec->ctx_RegEbx,
609 pCtxRec->ctx_RegEdi,
610 pCtxRec->ctx_RegEcx,
611 pCtxRec->ctx_RegEdx));
612
613 if (pCtxRec->ContextFlags & CONTEXT_SEGMENTS) /* check flags */
614 dprintf((" DS=%08x\n"
615 " ES=%08x\n"
616 " FS=%08x\n"
617 " GS=%08x\n",
618 pCtxRec->ctx_SegDs,
619 pCtxRec->ctx_SegEs,
620 pCtxRec->ctx_SegFs,
621 pCtxRec->ctx_SegGs));
622
623 if (pCtxRec->ContextFlags & CONTEXT_FLOATING_POINT) /* check flags */
624 {
625 ULONG ulCounter; /* temporary local counter for fp stack */
626
627 dprintf((" Env[0]=%08x Env[1]=%08x Env[2]=%08x Env[3]=%08x\n",
628 pCtxRec->ctx_env[0],
629 pCtxRec->ctx_env[1],
630 pCtxRec->ctx_env[2],
631 pCtxRec->ctx_env[3]));
632
633 dprintf((" Env[4]=%08x Env[5]=%08x Env[6]=%08x\n",
634 pCtxRec->ctx_env[4],
635 pCtxRec->ctx_env[5],
636 pCtxRec->ctx_env[6]));
637
638 for (ulCounter = 0;
639 ulCounter < 8; /* see TOOLKIT\INCLUDE\BSEEXPT.H, _CONTEXT structure */
640 ulCounter ++)
641 dprintf((" FP-Stack[%u] losig=%08x hisig=%08x signexp=%04x\n",
642 ulCounter,
643 pCtxRec->ctx_stack[0].losig,
644 pCtxRec->ctx_stack[0].hisig,
645 pCtxRec->ctx_stack[0].signexp));
646 }
647
648 dprintf(("---[End Of Exception Information]-----\n"));
649
650 /* from PPC DDK */
651#ifndef XCPT_CONTINUE_STOP
652#define XCPT_CONTINUE_STOP 0x00716668
653#endif
654
655// return (XCPT_CONTINUE_STOP);
656// return (XCPT_CONTINUE_SEARCH);
657}
658//******************************************************************************
659//******************************************************************************
660ERR _System OS2ExceptionHandler(PEXCEPTIONREPORTRECORD pERepRec,
661 PEXCEPTIONREGISTRATIONRECORD pERegRec,
662 PCONTEXTRECORD pCtxRec,
663 PVOID p)
664{
665// pERegRec->prev_structure = 0;
666 dprintfException(pERepRec, pERegRec, pCtxRec, p);
667
668 /* Access violation at a known location */
669 switch(pERepRec->ExceptionNum) {
670 case XCPT_FLOAT_DENORMAL_OPERAND:
671 case XCPT_FLOAT_DIVIDE_BY_ZERO:
672 case XCPT_FLOAT_INEXACT_RESULT:
673 case XCPT_FLOAT_INVALID_OPERATION:
674 case XCPT_FLOAT_OVERFLOW:
675 case XCPT_FLOAT_STACK_CHECK:
676 case XCPT_FLOAT_UNDERFLOW:
677 dprintf(("FPU exception, fix and continue\n"));
678 pCtxRec->ctx_env[0] |= 0x1F;
679 pCtxRec->ctx_stack[0].losig = 0;
680 pCtxRec->ctx_stack[0].hisig = 0;
681 pCtxRec->ctx_stack[0].signexp = 0;
682
683 return (ERR)(XCPT_CONTINUE_EXECUTION);
684
685 case XCPT_PROCESS_TERMINATE:
686 case XCPT_ASYNC_PROCESS_TERMINATE:
687 SetExceptionChain((ULONG)0);
688 return (XCPT_CONTINUE_SEARCH);
689
690 case XCPT_ACCESS_VIOLATION:
691 case XCPT_BREAKPOINT:
692 case XCPT_ARRAY_BOUNDS_EXCEEDED:
693 case XCPT_DATATYPE_MISALIGNMENT:
694 case XCPT_ILLEGAL_INSTRUCTION:
695 case XCPT_PRIVILEGED_INSTRUCTION:
696 case XCPT_INVALID_LOCK_SEQUENCE:
697 case XCPT_INTEGER_DIVIDE_BY_ZERO:
698 case XCPT_INTEGER_OVERFLOW:
699 case XCPT_SINGLE_STEP:
700 case XCPT_GUARD_PAGE_VIOLATION:
701 case XCPT_UNABLE_TO_GROW_STACK:
702 case XCPT_IN_PAGE_ERROR:
703 case XCPT_SIGNAL:
704 dprintf(("Continue and kill\n"));
705 pCtxRec->ctx_RegEip = (ULONG)KillWin32Process;
706 pCtxRec->ctx_RegEsp = pCtxRec->ctx_RegEsp + 0x10;
707 pCtxRec->ctx_RegEax = pERepRec->ExceptionNum;
708 pCtxRec->ctx_RegEbx = pCtxRec->ctx_RegEip;
709 return (ERR)(XCPT_CONTINUE_EXECUTION);
710
711 default: //non-continuable exceptions
712 return (XCPT_CONTINUE_SEARCH);
713 }
714 return (XCPT_CONTINUE_SEARCH);
715}
716//******************************************************************************
717//SvL: Replace original startup code exception handler
718extern BOOL fExeStarted;
719//******************************************************************************
720void ReplaceExceptionHandler()
721{
722 static BOOL fRegistered = FALSE;
723 PWINEXCEPTION_FRAME orgframe;
724 APIRET rc;
725 ULONGULONG timerval;
726
727 DisableFPUExceptions();
728
729 if(fExeStarted == FALSE)
730 return;
731
732 orgframe = QueryExceptionChain();
733 if((int)orgframe == 0 || (int)orgframe == -1)
734 return;
735
736 dprintf(("ReplaceExceptionHandler\n"));
737
738 StartupCodeHandler = orgframe->Handler;
739 orgframe->Handler = (PEXCEPTION_HANDLER)OS2ExceptionHandler;
740 orgframe->Prev = (_WINEXCEPTION_FRAME *)0;
741 SetExceptionChain((ULONG)-1);
742#if 0
743 if(fRegistered == FALSE) {
744#endif
745 dprintf(("New exception frame at %X\n", orgframe));
746 rc = DosSetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD)orgframe);
747 fRegistered = TRUE;
748#if 0
749 }
750 else {
751 while(orgframe && orgframe->Handler != (PEXCEPTION_HANDLER)OS2ExceptionHandler) {
752 orgframe = orgframe->Prev;
753 }
754 dprintf(("Restore old exception frame %X\n", orgframe));
755 if(orgframe) {
756 orgframe->Prev = (_WINEXCEPTION_FRAME *)0;
757 SetExceptionChain((ULONG)orgframe);
758 }
759 }
760#endif
761}
762//******************************************************************************
763//******************************************************************************
764
Note: See TracBrowser for help on using the repository browser.