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

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

Exception handler changes

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