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

Last change on this file since 4 was 4, checked in by ktk, 26 years ago

Import

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