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

Last change on this file since 100 was 100, checked in by phaller, 26 years ago

Add: added cvs variable $Id$ to the source files.

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