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

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

Fix: preparing support for HandleManager on kernel objects

File size: 25.0 KB
Line 
1/* $Id: exceptions.cpp,v 1.4 1999-06-17 21:51:59 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 %08xh at %08xh.",
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 %08xh",
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:%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 EBX=%08x ESI=%08x\n"
605 " ECX=%08x EDX=%08x EDI=%08x\n",
606 pCtxRec->ctx_RegEax,
607 pCtxRec->ctx_RegEbx,
608 pCtxRec->ctx_RegEsi,
609 pCtxRec->ctx_RegEcx,
610 pCtxRec->ctx_RegEdx,
611 pCtxRec->ctx_RegEdi));
612
613 if (pCtxRec->ContextFlags & CONTEXT_SEGMENTS) /* check flags */
614 dprintf((" DS=%04x ES=%08x"
615 " FS=%04x GS=%04x\n",
616 pCtxRec->ctx_SegDs,
617 pCtxRec->ctx_SegEs,
618 pCtxRec->ctx_SegFs,
619 pCtxRec->ctx_SegGs));
620
621 if (pCtxRec->ContextFlags & CONTEXT_FLOATING_POINT) /* check flags */
622 {
623 ULONG ulCounter; /* temporary local counter for fp stack */
624
625 dprintf((" Env[0]=%08x Env[1]=%08x Env[2]=%08x Env[3]=%08x\n",
626 pCtxRec->ctx_env[0],
627 pCtxRec->ctx_env[1],
628 pCtxRec->ctx_env[2],
629 pCtxRec->ctx_env[3]));
630
631 dprintf((" Env[4]=%08x Env[5]=%08x Env[6]=%08x\n",
632 pCtxRec->ctx_env[4],
633 pCtxRec->ctx_env[5],
634 pCtxRec->ctx_env[6]));
635
636 for (ulCounter = 0;
637 ulCounter < 8; /* see TOOLKIT\INCLUDE\BSEEXPT.H, _CONTEXT structure */
638 ulCounter ++)
639 dprintf((" FP-Stack[%u] losig=%08x hisig=%08x signexp=%04x\n",
640 ulCounter,
641 pCtxRec->ctx_stack[0].losig,
642 pCtxRec->ctx_stack[0].hisig,
643 pCtxRec->ctx_stack[0].signexp));
644 }
645
646 dprintf(("---[End Of Exception Information]-----\n"));
647
648 /* from PPC DDK */
649#ifndef XCPT_CONTINUE_STOP
650#define XCPT_CONTINUE_STOP 0x00716668
651#endif
652
653// return (XCPT_CONTINUE_STOP);
654// return (XCPT_CONTINUE_SEARCH);
655}
656//******************************************************************************
657//******************************************************************************
658ERR _System OS2ExceptionHandler(PEXCEPTIONREPORTRECORD pERepRec,
659 PEXCEPTIONREGISTRATIONRECORD pERegRec,
660 PCONTEXTRECORD pCtxRec,
661 PVOID p)
662{
663// pERegRec->prev_structure = 0;
664 dprintfException(pERepRec, pERegRec, pCtxRec, p);
665
666 /* Access violation at a known location */
667 switch(pERepRec->ExceptionNum) {
668 case XCPT_FLOAT_DENORMAL_OPERAND:
669 case XCPT_FLOAT_DIVIDE_BY_ZERO:
670 case XCPT_FLOAT_INEXACT_RESULT:
671 case XCPT_FLOAT_INVALID_OPERATION:
672 case XCPT_FLOAT_OVERFLOW:
673 case XCPT_FLOAT_STACK_CHECK:
674 case XCPT_FLOAT_UNDERFLOW:
675 dprintf(("FPU exception, fix and continue\n"));
676 pCtxRec->ctx_env[0] |= 0x1F;
677 pCtxRec->ctx_stack[0].losig = 0;
678 pCtxRec->ctx_stack[0].hisig = 0;
679 pCtxRec->ctx_stack[0].signexp = 0;
680
681 return (ERR)(XCPT_CONTINUE_EXECUTION);
682
683 case XCPT_PROCESS_TERMINATE:
684 case XCPT_ASYNC_PROCESS_TERMINATE:
685 SetExceptionChain((ULONG)0);
686 return (XCPT_CONTINUE_SEARCH);
687
688 case XCPT_ACCESS_VIOLATION:
689 case XCPT_BREAKPOINT:
690 case XCPT_ARRAY_BOUNDS_EXCEEDED:
691 case XCPT_DATATYPE_MISALIGNMENT:
692 case XCPT_ILLEGAL_INSTRUCTION:
693 case XCPT_PRIVILEGED_INSTRUCTION:
694 case XCPT_INVALID_LOCK_SEQUENCE:
695 case XCPT_INTEGER_DIVIDE_BY_ZERO:
696 case XCPT_INTEGER_OVERFLOW:
697 case XCPT_SINGLE_STEP:
698 case XCPT_GUARD_PAGE_VIOLATION:
699 case XCPT_UNABLE_TO_GROW_STACK:
700 case XCPT_IN_PAGE_ERROR:
701 case XCPT_SIGNAL:
702 dprintf(("Continue and kill\n"));
703 pCtxRec->ctx_RegEip = (ULONG)KillWin32Process;
704 pCtxRec->ctx_RegEsp = pCtxRec->ctx_RegEsp + 0x10;
705 pCtxRec->ctx_RegEax = pERepRec->ExceptionNum;
706 pCtxRec->ctx_RegEbx = pCtxRec->ctx_RegEip;
707 return (ERR)(XCPT_CONTINUE_EXECUTION);
708
709 default: //non-continuable exceptions
710 return (XCPT_CONTINUE_SEARCH);
711 }
712 return (XCPT_CONTINUE_SEARCH);
713}
714//******************************************************************************
715//SvL: Replace original startup code exception handler
716extern BOOL fExeStarted;
717//******************************************************************************
718void ReplaceExceptionHandler()
719{
720 static BOOL fRegistered = FALSE;
721 PWINEXCEPTION_FRAME orgframe;
722 APIRET rc;
723 ULONGULONG timerval;
724
725 DisableFPUExceptions();
726
727 if(fExeStarted == FALSE)
728 return;
729
730 orgframe = QueryExceptionChain();
731 if((int)orgframe == 0 || (int)orgframe == -1)
732 return;
733
734 dprintf(("ReplaceExceptionHandler\n"));
735
736 StartupCodeHandler = orgframe->Handler;
737 orgframe->Handler = (PEXCEPTION_HANDLER)OS2ExceptionHandler;
738 orgframe->Prev = (_WINEXCEPTION_FRAME *)0;
739 SetExceptionChain((ULONG)-1);
740#if 0
741 if(fRegistered == FALSE) {
742#endif
743 dprintf(("New exception frame at %X\n", orgframe));
744 rc = DosSetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD)orgframe);
745 fRegistered = TRUE;
746#if 0
747 }
748 else {
749 while(orgframe && orgframe->Handler != (PEXCEPTION_HANDLER)OS2ExceptionHandler) {
750 orgframe = orgframe->Prev;
751 }
752 dprintf(("Restore old exception frame %X\n", orgframe));
753 if(orgframe) {
754 orgframe->Prev = (_WINEXCEPTION_FRAME *)0;
755 SetExceptionChain((ULONG)orgframe);
756 }
757 }
758#endif
759}
760//******************************************************************************
761//******************************************************************************
762
Note: See TracBrowser for help on using the repository browser.