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

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

Fix: source beautification of exception.cpp, more debug information

File size: 28.2 KB
Line 
1/* $Id: exceptions.cpp,v 1.6 1999-07-06 09:49:45 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 <os2wrap.h> //Odin32 OS/2 api wrappers
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/*****************************************************************************
70 * Name : UINT SetErrorMode
71 * Purpose :
72 * Parameters: UINT fuErrorMode
73 * Variables :
74 * Result :
75 * Remark :
76 * Status :
77 *
78 * Author : Sander van Leeuwen [Tue, 1999/07/01 09:00]
79 *****************************************************************************/
80
81UINT WIN32API SetErrorMode(UINT fuErrorMode)
82{
83 UINT oldmode = CurrentErrorMode;
84
85 dprintf(("KERNEL32: SetErrorMode(%08xh)\n",
86 fuErrorMode));
87
88 CurrentErrorMode = fuErrorMode;
89
90 return(oldmode);
91}
92
93
94/*****************************************************************************
95 * Name : VOID _Pascal OS2RaiseException
96 * Purpose : Unwinds exception handlers (heavily influenced by Wine)
97 * Parameters: ...
98 * Variables :
99 * Result :
100 * Remark :
101 * Status :
102 *
103 * Author : Sander van Leeuwen [Tue, 1999/07/01 09:00]
104 *****************************************************************************/
105
106VOID _Pascal OS2RaiseException(DWORD dwExceptionCode,
107 DWORD dwExceptionFlags,
108 DWORD cArguments,
109 DWORD *lpArguments,
110 DWORD eip, DWORD esp, DWORD ebp, DWORD flags,
111 DWORD eax, DWORD ebx, DWORD ecx, DWORD edx,
112 DWORD edi, DWORD esi, DWORD cs, DWORD ds,
113 DWORD es, DWORD fs, DWORD gs, DWORD ss)
114{
115 PWINEXCEPTION_FRAME pframe;
116 WINEXCEPTION_RECORD record;
117 WINEXCEPTION_POINTERS ExceptionInfo;
118 WINCONTEXT context;
119 DWORD dispatch;
120 int rc;
121 int i;
122
123 dprintf(("KERNEL32: RaiseException(%08xh)\n",
124 dwExceptionCode));
125
126 /* compose an exception record */
127 record.ExceptionCode = dwExceptionCode;
128 record.ExceptionFlags = dwExceptionFlags;
129 record.ExceptionRecord = NULL;
130 record.NumberParameters = cArguments;
131 record.ExceptionAddress = (LPVOID)eip;
132
133 memset(&context, 0, sizeof(context));
134 context.ContextFlags = WINCONTEXT_FULL; //segments, integer, control
135 context.SegGs = gs;
136 context.SegFs = fs;
137 context.SegEs = es;
138 context.SegDs = ds;
139 context.Edi = edi;
140 context.Esi = esi;
141 context.Ebx = ebx;
142 context.Edx = edx;
143 context.Ecx = ecx;
144 context.Eax = eax;
145 context.Ebp = ebp;
146 context.Eip = eip;
147 context.SegCs = cs;
148 context.EFlags = flags;
149 context.Esp = esp;
150 context.SegSs = ss;
151
152 if(lpArguments)
153 {
154 for(i=0;
155 i<cArguments;
156 i++)
157 record.ExceptionInformation[i] = lpArguments[i];
158 }
159
160 // get chain of exception frames
161 rc = ExceptionContinueSearch;
162 pframe = QueryExceptionChain();
163
164 // walk the exception chain
165 while( (pframe != NULL) && (pframe != ((void *)0xFFFFFFFF)) )
166 {
167 dispatch=0;
168 rc = pframe->Handler(&record,
169 pframe,
170 &context,
171 &dispatch);
172 if(rc == ExceptionContinueExecution)
173 break;
174
175 pframe = pframe->Prev;
176 }
177
178 // and finally, the unhandled exception filter
179 if(rc == ExceptionContinueSearch && UnhandledExceptionFilter != NULL)
180 {
181 ExceptionInfo.ExceptionRecord = &record;
182 ExceptionInfo.ContextRecord = &context;
183
184 rc = UnhandledExceptionFilter(&ExceptionInfo);
185 }
186
187 // terminate the process
188 if(rc != ExceptionContinueExecution)
189 {
190 dprintf(("KERNEL32: RaiseException terminating process.\n"));
191 DosExit(EXIT_PROCESS, 0);
192 }
193
194 return;
195}
196
197
198/*****************************************************************************
199 * Name : int _Pascal OS2RtlUnwind
200 * Purpose : Unwinds exception handlers (heavily influenced by Wine)
201 * Parameters: ...
202 * Variables :
203 * Result :
204 * Remark :
205 * Status :
206 *
207 * Author : Sander van Leeuwen [Tue, 1999/07/01 09:00]
208 *****************************************************************************/
209
210int _Pascal OS2RtlUnwind(PWINEXCEPTION_FRAME pEndFrame,
211 LPVOID unusedEip,
212 PWINEXCEPTION_RECORD pRecord,
213 DWORD returnEax,
214 DWORD eip, DWORD esp, DWORD ebp, DWORD flags,
215 DWORD eax, DWORD ebx, DWORD ecx, DWORD edx,
216 DWORD edi, DWORD esi, DWORD cs, DWORD ds,
217 DWORD es, DWORD fs, DWORD gs, DWORD ss)
218{
219 WINEXCEPTION_RECORD record;
220 WINCONTEXT context;
221 DWORD dispatch;
222 int rc;
223
224 dprintf(("KERNEL32: RtlUnwind\n"));
225
226 memset(&context, 0, sizeof(context));
227 context.ContextFlags = WINCONTEXT_FULL; //segments, integer, control
228 context.SegGs = gs;
229 context.SegFs = fs;
230 context.SegEs = es;
231 context.SegDs = ds;
232 context.Edi = edi;
233 context.Esi = esi;
234 context.Ebx = ebx;
235 context.Edx = edx;
236 context.Ecx = ecx;
237 context.Eax = returnEax;
238 context.Ebp = ebp;
239 context.Eip = eip;
240 context.SegCs = cs;
241 context.EFlags = flags;
242 context.Esp = esp;
243 context.SegSs = ss;
244
245 /* build an exception record, if we do not have one */
246 if(!pRecord)
247 {
248 record.ExceptionCode = STATUS_INVALID_DISPOSITION;
249 record.ExceptionFlags = 0;
250 record.ExceptionRecord = NULL;
251 record.ExceptionAddress = (LPVOID)eip;
252 record.NumberParameters = 0;
253 pRecord = &record;
254 }
255
256 if(pEndFrame) pRecord->ExceptionFlags |= EH_UNWINDING;
257 else pRecord->ExceptionFlags |= EH_UNWINDING | EH_EXIT_UNWIND;
258
259 /* get chain of exception frames */
260 while((QueryExceptionChain() != NULL) &&
261 (QueryExceptionChain() != (void *)0xffffffff) &&
262 (QueryExceptionChain() != pEndFrame))
263 {
264 dispatch=0;
265 rc = QueryExceptionChain()->Handler(pRecord,
266 QueryExceptionChain(),
267 &context,
268 &dispatch);
269
270 if((rc == ExceptionCollidedUnwind) &&
271 (QueryExceptionChain() != (LPVOID)dispatch))
272 {
273 SetExceptionChain(dispatch);
274 }
275 else
276 if((QueryExceptionChain() != pEndFrame) &&
277 (QueryExceptionChain() != QueryExceptionChain()->Prev))
278 SetExceptionChain((DWORD)QueryExceptionChain()->Prev);
279 else
280 break;
281 }
282
283 if(pEndFrame == UNWIND_ALL)
284 {
285 dprintf(("KERNEL32: RtlUnwind terminating thread.\n"));
286 DosExit(EXIT_THREAD, 0);
287 }
288 return(0);
289}
290
291
292/*****************************************************************************
293 * Name : LONG WIN32API UnhandledExceptionFilter
294 * Purpose :
295 * Parameters: ...
296 * Variables :
297 * Result :
298 * Remark :
299 * Status :
300 *
301 * Author : Sander van Leeuwen [Tue, 1999/07/01 09:00]
302 *****************************************************************************/
303
304LONG WIN32API UnhandledExceptionFilter(PWINEXCEPTION_POINTERS lpexpExceptionInfo)
305{
306 char message[72];
307 DWORD rc;
308
309 dprintf(("KERNEL32: UnhandledExceptionFilter\n"));
310
311 if(CurrentUnhExceptionFlt && !(CurrentErrorMode & (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX)))
312 {
313 rc = CurrentUnhExceptionFlt(lpexpExceptionInfo);
314 if(rc != WINEXCEPTION_CONTINUE_SEARCH)
315 return rc;
316 }
317
318 sprintf(message,
319 "Unhandled exception 0x%08lx at address 0x%08lx.",
320 lpexpExceptionInfo->ExceptionRecord->ExceptionCode,
321 lpexpExceptionInfo->ExceptionRecord->ExceptionAddress);
322
323 WinMessageBox(HWND_DESKTOP,
324 HWND_DESKTOP,
325 message,
326 "Oh, nooo!",
327 0,
328 MB_OK | MB_ERROR);
329
330 return WINEXCEPTION_EXECUTE_HANDLER;
331}
332
333
334/*****************************************************************************
335 * Name : LPTOP_LEVEL_EXCEPTION_FILTER WIN32API SetUnhandledExceptionFilter
336 * Purpose :
337 * Parameters: ...
338 * Variables :
339 * Result :
340 * Remark :
341 * Status :
342 *
343 * Author : Sander van Leeuwen [Tue, 1999/07/01 09:00]
344 *****************************************************************************/
345
346LPTOP_LEVEL_EXCEPTION_FILTER WIN32API SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
347{
348 LPTOP_LEVEL_EXCEPTION_FILTER old = CurrentUnhExceptionFlt;
349
350 dprintf(("KERNEL32: SetUnhandledExceptionFilter to %X\n",
351 lpTopLevelExceptionFilter));
352
353 CurrentUnhExceptionFlt = lpTopLevelExceptionFilter;
354
355 return(old);
356}
357
358
359/*****************************************************************************
360 * Name : KillWin32Process
361 * Purpose :
362 * Parameters: ...
363 * Variables :
364 * Result :
365 * Remark :
366 * Status :
367 *
368 * Author : Sander van Leeuwen [Tue, 1999/07/01 09:00]
369 *****************************************************************************/
370
371
372//******************************************************************************
373extern "C" ULONG getEAX();
374extern "C" ULONG getEBX();
375//******************************************************************************
376void KillWin32Process(void)
377{
378 char excptmsg[64];
379 ULONG excptaddr, excptnr;
380
381 excptnr = getEAX();
382 excptaddr = getEBX();
383
384 dprintf(("KERNEL32: KillWin32Process: Do you feel lucky, punk?!\n"));
385// sprintf(excptmsg, "Fatal Exception %X at %X", excptnr, excptaddr);
386// WinMessageBox(HWND_DESKTOP, NULL, excptmsg, "Win32 for OS/2", 0, MB_ERROR | MB_OK);
387 SetExceptionChain((ULONG)0);
388 DosExit(EXIT_PROCESS, 666);
389}
390
391
392//******************************************************************************
393APIRET APIENTRY DosQueryModFromEIP (PULONG pulModule,
394 PULONG pulObject,
395 ULONG ulBufferLength,
396 PSZ pszBuffer,
397 PULONG pulOffset,
398 ULONG ulEIP);
399//******************************************************************************
400
401
402/*****************************************************************************
403 * Name : void static dprintfException
404 * Purpose : log the exception to win32os2.log
405 * Parameters: ...
406 * Variables :
407 * Result :
408 * Remark :
409 * Status :
410 *
411 * Author : Patrick Haller [Tue, 1999/07/01 09:00]
412 *****************************************************************************/
413
414void static dprintfException(PEXCEPTIONREPORTRECORD pERepRec,
415 PEXCEPTIONREGISTRATIONRECORD pERegRec,
416 PCONTEXTRECORD pCtxRec,
417 PVOID p)
418{
419 PSZ pszExceptionName = "<unknown>"; /* points to name/type excpt */
420 char szData[128]; /* local storage for excpt dep. information */
421 char szData2[128]; /* local storage for excpt dep. information */
422 APIRET rc = XCPT_CONTINUE_SEARCH; /* excpt-dep. code */
423 BOOL fExcptSoftware = FALSE; /* software/hardware gen. exceptn */
424 BOOL fExcptFatal = TRUE; /* fatal exception ? */
425 BOOL fExcptPortable = TRUE; /* portability of exception */
426 PPIB pPIB; /* process information block */
427 PTIB pTIB; /* thread information block */
428 ULONG ulModule; /* module number */
429 ULONG ulObject; /* object number within the module */
430 CHAR szModule[260]; /* buffer for the module name */
431 ULONG ulOffset; /* offset within the object within the module */
432
433 szData[0] = 0; /* initialize */
434 szData2[0] = 0; /* initialize */
435 switch(pERepRec->ExceptionNum) /* take according action */
436 {
437 /* portable, non-fatal software-generated exceptions */
438 case XCPT_GUARD_PAGE_VIOLATION:
439 pszExceptionName = "Guard Page Violation";
440 sprintf(szData,
441 "R/W %08xh at %08xh.",
442 pERepRec->ExceptionInfo[0],
443 pERepRec->ExceptionInfo[1]);
444 fExcptSoftware = TRUE;
445 fExcptFatal = FALSE;
446 rc = XCPT_CONTINUE_EXECUTION;
447 break;
448
449 case XCPT_UNABLE_TO_GROW_STACK:
450 pszExceptionName = "Unable To Grow Stack";
451 fExcptSoftware = TRUE;
452 fExcptFatal = FALSE;
453 rc = XCPT_CONTINUE_EXECUTION;
454 break;
455
456 /* portable, fatal, hardware-generated exceptions */
457 case XCPT_ACCESS_VIOLATION:
458 pszExceptionName = "Access Violation";
459 /* sprintf (szData, "Access type %08x at %08x.", pERepRec->ExceptionInfo[0],
460 pERepRec->ExceptionInfo[1]); */
461 switch (pERepRec->ExceptionInfo[0])
462 {
463 case XCPT_READ_ACCESS:
464 sprintf (szData,
465 "Read Access at address %08xh",
466 pERepRec->ExceptionInfo[1]);
467 break;
468
469 case XCPT_WRITE_ACCESS:
470 sprintf (szData,
471 "Write Access at address %08x",
472 pERepRec->ExceptionInfo[1]);
473 break;
474
475 case XCPT_SPACE_ACCESS:
476 sprintf (szData,
477 "Space Access at selector %08x",
478 pERepRec->ExceptionInfo[1]);
479 break;
480
481 case XCPT_LIMIT_ACCESS:
482 strcpy (szData,
483 "Limit Access");
484 break;
485
486 case XCPT_UNKNOWN_ACCESS:
487 strcpy (szData,
488 "Unknown Access");
489 break;
490
491 default:
492 strcpy (szData,
493 "(Invalid Access Code)");
494 break;
495 }
496 break;
497
498 case XCPT_INTEGER_DIVIDE_BY_ZERO:
499 pszExceptionName = "Division By Zero (Integer)";
500 break;
501
502 case XCPT_FLOAT_DIVIDE_BY_ZERO:
503 pszExceptionName = "Division By Zero (Float)";
504 break;
505
506 case XCPT_FLOAT_INVALID_OPERATION:
507 pszExceptionName = "Invalid Floating Point Operation";
508 break;
509
510 case XCPT_ILLEGAL_INSTRUCTION:
511 pszExceptionName = "Illegal Instruction";
512 break;
513
514 case XCPT_PRIVILEGED_INSTRUCTION:
515 pszExceptionName = "Privileged Instruction";
516 break;
517
518 case XCPT_INTEGER_OVERFLOW:
519 pszExceptionName = "Integer Overflow";
520 break;
521
522 case XCPT_FLOAT_OVERFLOW:
523 pszExceptionName = "Floating Point Overflow";
524 break;
525
526 case XCPT_FLOAT_UNDERFLOW:
527 pszExceptionName = "Floating Point Underflow";
528 break;
529
530 case XCPT_FLOAT_DENORMAL_OPERAND:
531 pszExceptionName = "Floating Point Denormal Operand";
532 break;
533
534 case XCPT_FLOAT_INEXACT_RESULT:
535 pszExceptionName = "Floating Point Inexact Result";
536 break;
537
538 case XCPT_FLOAT_STACK_CHECK:
539 pszExceptionName = "Floating Point Stack Check";
540 break;
541
542 case XCPT_DATATYPE_MISALIGNMENT:
543 pszExceptionName = "Datatype Misalignment";
544 sprintf(szData,
545 "R/W %08x alignment %08x at %08x.",
546 pERepRec->ExceptionInfo[0],
547 pERepRec->ExceptionInfo[1],
548 pERepRec->ExceptionInfo[2]);
549 break;
550
551 case XCPT_BREAKPOINT:
552 pszExceptionName = "Breakpoint (don't debug me! :)";
553 break;
554
555 case XCPT_SINGLE_STEP:
556 pszExceptionName = "Single Step (don't debug me! :)";
557 break;
558
559 /* portable, fatal, software-generated exceptions */
560 case XCPT_IN_PAGE_ERROR:
561 pszExceptionName = "In Page Error";
562 sprintf(szData,
563 "at %08x.",
564 pERepRec->ExceptionInfo[0]);
565 fExcptSoftware = TRUE;
566 break;
567
568 case XCPT_PROCESS_TERMINATE:
569 pszExceptionName = "Process Termination";
570 fExcptSoftware = TRUE;
571 break;
572
573 case XCPT_ASYNC_PROCESS_TERMINATE:
574 pszExceptionName = "Process Termination (async)";
575 sprintf(szData,
576 "terminating thread TID=%u",
577 pERepRec->ExceptionInfo[0]);
578 fExcptSoftware = TRUE;
579 break;
580
581 case XCPT_NONCONTINUABLE_EXCEPTION:
582 pszExceptionName = "Noncontinuable Exception";
583 fExcptSoftware = TRUE;
584 break;
585
586 case XCPT_INVALID_DISPOSITION:
587 pszExceptionName = "Invalid Disposition";
588 fExcptSoftware = TRUE;
589 break;
590
591 /* non-portable, fatal exceptions */
592 case XCPT_INVALID_LOCK_SEQUENCE:
593 pszExceptionName = "Invalid Lock Sequence";
594 fExcptSoftware = TRUE;
595 fExcptPortable = FALSE;
596 break;
597
598 case XCPT_ARRAY_BOUNDS_EXCEEDED:
599 pszExceptionName = "Array Bounds Exceeded";
600 fExcptSoftware = TRUE;
601 fExcptPortable = FALSE;
602 break;
603
604 /* unwind operation exceptions */
605 case XCPT_UNWIND:
606 pszExceptionName = "Unwind Exception";
607 fExcptSoftware = TRUE;
608 fExcptPortable = FALSE;
609 break;
610
611 case XCPT_BAD_STACK:
612 pszExceptionName = "Unwind Exception, Bad Stack";
613 fExcptSoftware = TRUE;
614 fExcptPortable = FALSE;
615 break;
616
617 case XCPT_INVALID_UNWIND_TARGET:
618 pszExceptionName = "Unwind Exception, Invalid Target";
619 fExcptSoftware = TRUE;
620 fExcptPortable = FALSE;
621 break;
622
623 /* fatal signal exceptions */
624 case XCPT_SIGNAL:
625 pszExceptionName = "Signal";
626 sprintf(szData,
627 "Signal Number = %08x",
628 pERepRec->ExceptionInfo[0]);
629 fExcptSoftware = TRUE;
630 fExcptPortable = FALSE;
631
632 switch (pERepRec->ExceptionInfo[0]) /* resolve signal information */
633 {
634 case XCPT_SIGNAL_INTR:
635 pszExceptionName = "Signal (Interrupt)";
636 break;
637
638 case XCPT_SIGNAL_KILLPROC:
639 pszExceptionName = "Signal (Kill Process)";
640 break;
641
642 case XCPT_SIGNAL_BREAK:
643 pszExceptionName = "Signal (Break)";
644 break;
645 }
646 break;
647
648 default:
649 pszExceptionName = "(unknown exception code)";
650 sprintf(szData,
651 "Exception Code = %08x",
652 pERepRec->ExceptionNum);
653 }
654
655
656 /* now dump the information to the logfile */
657 dprintf(("---[Exception Information]------------\n"));
658 sprintf(szData2,
659 " %s (",
660 pszExceptionName);
661
662 if (fExcptSoftware == TRUE) /* software or hardware generated ? */
663 strcat (szData2, "software generated,");
664 else
665 strcat (szData2, "hardware generated,");
666
667 if (fExcptPortable == TRUE) /* portable exception ? */
668 strcat (szData2, "portable,");
669 else
670 strcat (szData2, "non-portable,");
671
672 if (fExcptFatal == TRUE) /* fatal exception ? */
673 strcat (szData2, "fatal");
674 else
675 strcat (szData2, "non-fatal");
676
677 strcat (szData2, /* add trailing brace */
678 ")\n");
679
680
681 dprintf((szData2));
682
683 if (szData[0] != 0) /* see if there is an additional entry */
684 dprintf((" %s\n",
685 szData));
686
687 rc = DosQueryModFromEIP(&ulModule,
688 &ulObject,
689 sizeof(szModule),
690 szModule,
691 &ulOffset,
692 (ULONG)pERepRec->ExceptionAddress);
693
694 dprintf((" Exception Address = %08x ",
695 pERepRec->ExceptionAddress));
696
697 if (rc == NO_ERROR)
698 dprintf(("%s (#%u), obj #%u:%08x\n",
699 szModule,
700 ulModule,
701 ulObject,
702 ulOffset));
703 else
704 dprintf(("\n"));
705
706
707 rc = DosGetInfoBlocks (&pTIB, /* query kernel information blocks */
708 &pPIB);
709 if (rc == NO_ERROR)
710 {
711 dprintf((" Thread: Ordinal TID: %u, TID: %u, Priority: %04xh\n",
712 pTIB->tib_ordinal,
713 pTIB->tib_ptib2->tib2_ultid,
714 pTIB->tib_ptib2->tib2_ulpri));
715
716 dprintf((" Process: PID: %u, Parent: %u, Status: %u\n",
717 pPIB->pib_ulpid,
718 pPIB->pib_ulppid,
719 pPIB->pib_flstatus));
720 }
721
722 if (pCtxRec->ContextFlags & CONTEXT_CONTROL) /* check flags */
723 dprintf((" SS:ESP=%04x:%08x EFLAGS=%08x\n"
724 " CS:EIP=%04x:%08x EBP =%08x\n",
725 pCtxRec->ctx_SegSs,
726 pCtxRec->ctx_RegEsp,
727 pCtxRec->ctx_EFlags,
728 pCtxRec->ctx_SegCs,
729 pCtxRec->ctx_RegEip,
730 pCtxRec->ctx_RegEbp));
731
732 if (pCtxRec->ContextFlags & CONTEXT_INTEGER) /* check flags */
733 dprintf((" EAX=%08x EBX=%08x ESI=%08x\n"
734 " ECX=%08x EDX=%08x EDI=%08x\n",
735 pCtxRec->ctx_RegEax,
736 pCtxRec->ctx_RegEbx,
737 pCtxRec->ctx_RegEsi,
738 pCtxRec->ctx_RegEcx,
739 pCtxRec->ctx_RegEdx,
740 pCtxRec->ctx_RegEdi));
741
742 if (pCtxRec->ContextFlags & CONTEXT_SEGMENTS) /* check flags */
743 dprintf((" DS=%04x ES=%08x"
744 " FS=%04x GS=%04x\n",
745 pCtxRec->ctx_SegDs,
746 pCtxRec->ctx_SegEs,
747 pCtxRec->ctx_SegFs,
748 pCtxRec->ctx_SegGs));
749
750 if (pCtxRec->ContextFlags & CONTEXT_FLOATING_POINT) /* check flags */
751 {
752 ULONG ulCounter; /* temporary local counter for fp stack */
753
754 dprintf((" Env[0]=%08x Env[1]=%08x Env[2]=%08x Env[3]=%08x\n",
755 pCtxRec->ctx_env[0],
756 pCtxRec->ctx_env[1],
757 pCtxRec->ctx_env[2],
758 pCtxRec->ctx_env[3]));
759
760 dprintf((" Env[4]=%08x Env[5]=%08x Env[6]=%08x\n",
761 pCtxRec->ctx_env[4],
762 pCtxRec->ctx_env[5],
763 pCtxRec->ctx_env[6]));
764
765 for (ulCounter = 0;
766 ulCounter < 8; /* see TOOLKIT\INCLUDE\BSEEXPT.H, _CONTEXT structure */
767 ulCounter ++)
768 dprintf((" FP-Stack[%u] losig=%08x hisig=%08x signexp=%04x\n",
769 ulCounter,
770 pCtxRec->ctx_stack[0].losig,
771 pCtxRec->ctx_stack[0].hisig,
772 pCtxRec->ctx_stack[0].signexp));
773 }
774
775 dprintf(("---[End Of Exception Information]-----\n"));
776}
777
778
779/*****************************************************************************
780 * Name : ERR _System OS2ExceptionHandler
781 * Purpose :
782 * Parameters: ...
783 * Variables :
784 * Result :
785 * Remark :
786 * Status :
787 *
788 * Author : Patrick Haller [Tue, 1999/07/01 09:00]
789 *****************************************************************************/
790 /* from PPC DDK */
791#ifndef XCPT_CONTINUE_STOP
792#define XCPT_CONTINUE_STOP 0x00716668
793#endif
794
795ERR _System OS2ExceptionHandler(PEXCEPTIONREPORTRECORD pERepRec,
796 PEXCEPTIONREGISTRATIONRECORD pERegRec,
797 PCONTEXTRECORD pCtxRec,
798 PVOID p)
799{
800 // pERegRec->prev_structure = 0;
801 dprintfException(pERepRec, pERegRec, pCtxRec, p);
802
803 /* Access violation at a known location */
804 switch(pERepRec->ExceptionNum)
805 {
806 case XCPT_FLOAT_DENORMAL_OPERAND:
807 case XCPT_FLOAT_DIVIDE_BY_ZERO:
808 case XCPT_FLOAT_INEXACT_RESULT:
809 case XCPT_FLOAT_INVALID_OPERATION:
810 case XCPT_FLOAT_OVERFLOW:
811 case XCPT_FLOAT_STACK_CHECK:
812 case XCPT_FLOAT_UNDERFLOW:
813 dprintf(("KERNEL32: OS2ExceptionHandler: FPU exception, fix and continue\n"));
814 pCtxRec->ctx_env[0] |= 0x1F;
815 pCtxRec->ctx_stack[0].losig = 0;
816 pCtxRec->ctx_stack[0].hisig = 0;
817 pCtxRec->ctx_stack[0].signexp = 0;
818
819 return (ERR)(XCPT_CONTINUE_EXECUTION);
820
821 case XCPT_PROCESS_TERMINATE:
822 case XCPT_ASYNC_PROCESS_TERMINATE:
823 SetExceptionChain((ULONG)0);
824 return (XCPT_CONTINUE_SEARCH);
825
826 case XCPT_ACCESS_VIOLATION:
827 case XCPT_BREAKPOINT:
828 case XCPT_ARRAY_BOUNDS_EXCEEDED:
829 case XCPT_DATATYPE_MISALIGNMENT:
830 case XCPT_ILLEGAL_INSTRUCTION:
831 case XCPT_PRIVILEGED_INSTRUCTION:
832 case XCPT_INVALID_LOCK_SEQUENCE:
833 case XCPT_INTEGER_DIVIDE_BY_ZERO:
834 case XCPT_INTEGER_OVERFLOW:
835 case XCPT_SINGLE_STEP:
836 case XCPT_GUARD_PAGE_VIOLATION:
837 case XCPT_UNABLE_TO_GROW_STACK:
838 case XCPT_IN_PAGE_ERROR:
839 case XCPT_SIGNAL:
840 dprintf(("KERNEL32: OS2ExceptionHandler: Continue and kill\n"));
841 pCtxRec->ctx_RegEip = (ULONG)KillWin32Process;
842 pCtxRec->ctx_RegEsp = pCtxRec->ctx_RegEsp + 0x10;
843 pCtxRec->ctx_RegEax = pERepRec->ExceptionNum;
844 pCtxRec->ctx_RegEbx = pCtxRec->ctx_RegEip;
845 return (ERR)(XCPT_CONTINUE_EXECUTION);
846
847 default: //non-continuable exceptions
848 return (XCPT_CONTINUE_SEARCH);
849 }
850 return (XCPT_CONTINUE_SEARCH);
851}
852
853
854/*****************************************************************************
855 * Name : void ReplaceExceptionHandler
856 * Purpose :
857 * Parameters: ...
858 * Variables :
859 * Result :
860 * Remark :
861 * Status :
862 *
863 * Author : Sander van Leeuwen [Tue, 1999/07/01 09:00]
864 *****************************************************************************/
865
866//******************************************************************************
867//SvL: Replace original startup code exception handler
868extern BOOL fExeStarted;
869//******************************************************************************
870void ReplaceExceptionHandler()
871{
872 static BOOL fRegistered = FALSE;
873 PWINEXCEPTION_FRAME orgframe;
874 APIRET rc;
875 ULONGULONG timerval;
876
877 DisableFPUExceptions();
878
879 if(fExeStarted == FALSE)
880 return;
881
882 orgframe = QueryExceptionChain();
883 if((int)orgframe == 0 ||
884 (int)orgframe == -1)
885 return;
886
887 dprintf(("KERNEL32: ReplaceExceptionHandler\n"));
888
889 StartupCodeHandler = orgframe->Handler;
890 orgframe->Handler = (PEXCEPTION_HANDLER)OS2ExceptionHandler;
891 orgframe->Prev = (_WINEXCEPTION_FRAME *)0;
892 SetExceptionChain((ULONG)-1);
893
894#if 0
895 if(fRegistered == FALSE)
896 {
897#endif
898
899 dprintf(("KERNEL32: ReplaceExceptionHandler: New exception frame at %X\n",
900 orgframe));
901 rc = DosSetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD)orgframe);
902 fRegistered = TRUE;
903
904#if 0
905 }
906 else
907 {
908 while(orgframe && orgframe->Handler != (PEXCEPTION_HANDLER)OS2ExceptionHandler)
909 {
910 orgframe = orgframe->Prev;
911 }
912
913 dprintf(("KERNEL32: ReplaceExceptionHandler: Restore old exception frame %X\n",
914 orgframe));
915 if(orgframe)
916 {
917 orgframe->Prev = (_WINEXCEPTION_FRAME *)0;
918 SetExceptionChain((ULONG)orgframe);
919 }
920 }
921#endif
922}
923
Note: See TracBrowser for help on using the repository browser.