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

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

Add: interactive user control for exception handling dialog (abort, retry, ignore)

File size: 30.7 KB
Line 
1/* $Id: exceptions.cpp,v 1.9 1999-08-05 13:11:38 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_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 "except.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?!\n"));
453// sprintf(excptmsg, "Fatal Exception %X at %X", excptnr, excptaddr);
454// WinMessageBox(HWND_DESKTOP, NULL, excptmsg, "Win32 for OS/2", 0, MB_ERROR | MB_OK);
455 SetExceptionChain((ULONG)0);
456 DosExit(EXIT_PROCESS, 666);
457}
458
459
460//******************************************************************************
461APIRET APIENTRY DosQueryModFromEIP (PULONG pulModule,
462 PULONG pulObject,
463 ULONG ulBufferLength,
464 PSZ pszBuffer,
465 PULONG pulOffset,
466 ULONG ulEIP);
467//******************************************************************************
468
469
470/*****************************************************************************
471 * Name : void static dprintfException
472 * Purpose : log the exception to win32os2.log
473 * Parameters: ...
474 * Variables :
475 * Result :
476 * Remark :
477 * Status :
478 *
479 * Author : Patrick Haller [Tue, 1999/07/01 09:00]
480 *****************************************************************************/
481
482void static dprintfException(PEXCEPTIONREPORTRECORD pERepRec,
483 PEXCEPTIONREGISTRATIONRECORD pERegRec,
484 PCONTEXTRECORD pCtxRec,
485 PVOID p)
486{
487 PSZ pszExceptionName = "<unknown>"; /* points to name/type excpt */
488 char szData[128]; /* local storage for excpt dep. information */
489 char szData2[128]; /* local storage for excpt dep. information */
490 APIRET rc = XCPT_CONTINUE_SEARCH; /* excpt-dep. code */
491 BOOL fExcptSoftware = FALSE; /* software/hardware gen. exceptn */
492 BOOL fExcptFatal = TRUE; /* fatal exception ? */
493 BOOL fExcptPortable = TRUE; /* portability of exception */
494 PPIB pPIB; /* process information block */
495 PTIB pTIB; /* thread information block */
496 ULONG ulModule; /* module number */
497 ULONG ulObject; /* object number within the module */
498 CHAR szModule[260]; /* buffer for the module name */
499 ULONG ulOffset; /* offset within the object within the module */
500
501 szData[0] = 0; /* initialize */
502 szData2[0] = 0; /* initialize */
503 switch(pERepRec->ExceptionNum) /* take according action */
504 {
505 /* portable, non-fatal software-generated exceptions */
506 case XCPT_GUARD_PAGE_VIOLATION:
507 pszExceptionName = "Guard Page Violation";
508 sprintf(szData,
509 "R/W %08xh at %08xh.",
510 pERepRec->ExceptionInfo[0],
511 pERepRec->ExceptionInfo[1]);
512 fExcptSoftware = TRUE;
513 fExcptFatal = FALSE;
514 rc = XCPT_CONTINUE_EXECUTION;
515 break;
516
517 case XCPT_UNABLE_TO_GROW_STACK:
518 pszExceptionName = "Unable To Grow Stack";
519 fExcptSoftware = TRUE;
520 fExcptFatal = FALSE;
521 rc = XCPT_CONTINUE_EXECUTION;
522 break;
523
524 /* portable, fatal, hardware-generated exceptions */
525 case XCPT_ACCESS_VIOLATION:
526 pszExceptionName = "Access Violation";
527 /* sprintf (szData, "Access type %08x at %08x.", pERepRec->ExceptionInfo[0],
528 pERepRec->ExceptionInfo[1]); */
529 switch (pERepRec->ExceptionInfo[0])
530 {
531 case XCPT_READ_ACCESS:
532 sprintf (szData,
533 "Read Access at address %08xh",
534 pERepRec->ExceptionInfo[1]);
535 break;
536
537 case XCPT_WRITE_ACCESS:
538 sprintf (szData,
539 "Write Access at address %08x",
540 pERepRec->ExceptionInfo[1]);
541 break;
542
543 case XCPT_SPACE_ACCESS:
544 sprintf (szData,
545 "Space Access at selector %08x",
546 pERepRec->ExceptionInfo[1]);
547 break;
548
549 case XCPT_LIMIT_ACCESS:
550 strcpy (szData,
551 "Limit Access");
552 break;
553
554 case XCPT_UNKNOWN_ACCESS:
555 strcpy (szData,
556 "Unknown Access");
557 break;
558
559 default:
560 strcpy (szData,
561 "(Invalid Access Code)");
562 break;
563 }
564 break;
565
566 case XCPT_INTEGER_DIVIDE_BY_ZERO:
567 pszExceptionName = "Division By Zero (Integer)";
568 break;
569
570 case XCPT_FLOAT_DIVIDE_BY_ZERO:
571 pszExceptionName = "Division By Zero (Float)";
572 break;
573
574 case XCPT_FLOAT_INVALID_OPERATION:
575 pszExceptionName = "Invalid Floating Point Operation";
576 break;
577
578 case XCPT_ILLEGAL_INSTRUCTION:
579 pszExceptionName = "Illegal Instruction";
580 break;
581
582 case XCPT_PRIVILEGED_INSTRUCTION:
583 pszExceptionName = "Privileged Instruction";
584 break;
585
586 case XCPT_INTEGER_OVERFLOW:
587 pszExceptionName = "Integer Overflow";
588 break;
589
590 case XCPT_FLOAT_OVERFLOW:
591 pszExceptionName = "Floating Point Overflow";
592 break;
593
594 case XCPT_FLOAT_UNDERFLOW:
595 pszExceptionName = "Floating Point Underflow";
596 break;
597
598 case XCPT_FLOAT_DENORMAL_OPERAND:
599 pszExceptionName = "Floating Point Denormal Operand";
600 break;
601
602 case XCPT_FLOAT_INEXACT_RESULT:
603 pszExceptionName = "Floating Point Inexact Result";
604 break;
605
606 case XCPT_FLOAT_STACK_CHECK:
607 pszExceptionName = "Floating Point Stack Check";
608 break;
609
610 case XCPT_DATATYPE_MISALIGNMENT:
611 pszExceptionName = "Datatype Misalignment";
612 sprintf(szData,
613 "R/W %08x alignment %08x at %08x.",
614 pERepRec->ExceptionInfo[0],
615 pERepRec->ExceptionInfo[1],
616 pERepRec->ExceptionInfo[2]);
617 break;
618
619 case XCPT_BREAKPOINT:
620 pszExceptionName = "Breakpoint (don't debug me! :)";
621 break;
622
623 case XCPT_SINGLE_STEP:
624 pszExceptionName = "Single Step (don't debug me! :)";
625 break;
626
627 /* portable, fatal, software-generated exceptions */
628 case XCPT_IN_PAGE_ERROR:
629 pszExceptionName = "In Page Error";
630 sprintf(szData,
631 "at %08x.",
632 pERepRec->ExceptionInfo[0]);
633 fExcptSoftware = TRUE;
634 break;
635
636 case XCPT_PROCESS_TERMINATE:
637 pszExceptionName = "Process Termination";
638 fExcptSoftware = TRUE;
639 break;
640
641 case XCPT_ASYNC_PROCESS_TERMINATE:
642 pszExceptionName = "Process Termination (async)";
643 sprintf(szData,
644 "terminating thread TID=%u",
645 pERepRec->ExceptionInfo[0]);
646 fExcptSoftware = TRUE;
647 break;
648
649 case XCPT_NONCONTINUABLE_EXCEPTION:
650 pszExceptionName = "Noncontinuable Exception";
651 fExcptSoftware = TRUE;
652 break;
653
654 case XCPT_INVALID_DISPOSITION:
655 pszExceptionName = "Invalid Disposition";
656 fExcptSoftware = TRUE;
657 break;
658
659 /* non-portable, fatal exceptions */
660 case XCPT_INVALID_LOCK_SEQUENCE:
661 pszExceptionName = "Invalid Lock Sequence";
662 fExcptSoftware = TRUE;
663 fExcptPortable = FALSE;
664 break;
665
666 case XCPT_ARRAY_BOUNDS_EXCEEDED:
667 pszExceptionName = "Array Bounds Exceeded";
668 fExcptSoftware = TRUE;
669 fExcptPortable = FALSE;
670 break;
671
672 /* unwind operation exceptions */
673 case XCPT_UNWIND:
674 pszExceptionName = "Unwind Exception";
675 fExcptSoftware = TRUE;
676 fExcptPortable = FALSE;
677 break;
678
679 case XCPT_BAD_STACK:
680 pszExceptionName = "Unwind Exception, Bad Stack";
681 fExcptSoftware = TRUE;
682 fExcptPortable = FALSE;
683 break;
684
685 case XCPT_INVALID_UNWIND_TARGET:
686 pszExceptionName = "Unwind Exception, Invalid Target";
687 fExcptSoftware = TRUE;
688 fExcptPortable = FALSE;
689 break;
690
691 /* fatal signal exceptions */
692 case XCPT_SIGNAL:
693 pszExceptionName = "Signal";
694 sprintf(szData,
695 "Signal Number = %08x",
696 pERepRec->ExceptionInfo[0]);
697 fExcptSoftware = TRUE;
698 fExcptPortable = FALSE;
699
700 switch (pERepRec->ExceptionInfo[0]) /* resolve signal information */
701 {
702 case XCPT_SIGNAL_INTR:
703 pszExceptionName = "Signal (Interrupt)";
704 break;
705
706 case XCPT_SIGNAL_KILLPROC:
707 pszExceptionName = "Signal (Kill Process)";
708 break;
709
710 case XCPT_SIGNAL_BREAK:
711 pszExceptionName = "Signal (Break)";
712 break;
713 }
714 break;
715
716 default:
717 pszExceptionName = "(unknown exception code)";
718 sprintf(szData,
719 "Exception Code = %08x",
720 pERepRec->ExceptionNum);
721 }
722
723
724 /* now dump the information to the logfile */
725 dprintf(("---[Exception Information]------------\n"));
726 sprintf(szData2,
727 " %s (",
728 pszExceptionName);
729
730 if (fExcptSoftware == TRUE) /* software or hardware generated ? */
731 strcat (szData2, "software generated,");
732 else
733 strcat (szData2, "hardware generated,");
734
735 if (fExcptPortable == TRUE) /* portable exception ? */
736 strcat (szData2, "portable,");
737 else
738 strcat (szData2, "non-portable,");
739
740 if (fExcptFatal == TRUE) /* fatal exception ? */
741 strcat (szData2, "fatal");
742 else
743 strcat (szData2, "non-fatal");
744
745 strcat (szData2, /* add trailing brace */
746 ")\n");
747
748
749 dprintf((szData2));
750
751 if (szData[0] != 0) /* see if there is an additional entry */
752 dprintf((" %s\n",
753 szData));
754
755 rc = DosQueryModFromEIP(&ulModule,
756 &ulObject,
757 sizeof(szModule),
758 szModule,
759 &ulOffset,
760 (ULONG)pERepRec->ExceptionAddress);
761
762 dprintf((" Exception Address = %08x ",
763 pERepRec->ExceptionAddress));
764
765 if (rc == NO_ERROR)
766 dprintf(("%s (#%u), obj #%u:%08x\n",
767 szModule,
768 ulModule,
769 ulObject,
770 ulOffset));
771 else
772 dprintf(("\n"));
773
774
775 rc = DosGetInfoBlocks (&pTIB, /* query kernel information blocks */
776 &pPIB);
777 if (rc == NO_ERROR)
778 {
779 dprintf((" Thread: Ordinal TID: %u, TID: %u, Priority: %04xh\n",
780 pTIB->tib_ordinal,
781 pTIB->tib_ptib2->tib2_ultid,
782 pTIB->tib_ptib2->tib2_ulpri));
783
784 dprintf((" Process: PID: %u, Parent: %u, Status: %u\n",
785 pPIB->pib_ulpid,
786 pPIB->pib_ulppid,
787 pPIB->pib_flstatus));
788 }
789
790 if (pCtxRec->ContextFlags & CONTEXT_CONTROL) /* check flags */
791 dprintf((" SS:ESP=%04x:%08x EFLAGS=%08x\n"
792 " CS:EIP=%04x:%08x EBP =%08x\n",
793 pCtxRec->ctx_SegSs,
794 pCtxRec->ctx_RegEsp,
795 pCtxRec->ctx_EFlags,
796 pCtxRec->ctx_SegCs,
797 pCtxRec->ctx_RegEip,
798 pCtxRec->ctx_RegEbp));
799
800 if (pCtxRec->ContextFlags & CONTEXT_INTEGER) /* check flags */
801 dprintf((" EAX=%08x EBX=%08x ESI=%08x\n"
802 " ECX=%08x EDX=%08x EDI=%08x\n",
803 pCtxRec->ctx_RegEax,
804 pCtxRec->ctx_RegEbx,
805 pCtxRec->ctx_RegEsi,
806 pCtxRec->ctx_RegEcx,
807 pCtxRec->ctx_RegEdx,
808 pCtxRec->ctx_RegEdi));
809
810 if (pCtxRec->ContextFlags & CONTEXT_SEGMENTS) /* check flags */
811 dprintf((" DS=%04x ES=%08x"
812 " FS=%04x GS=%04x\n",
813 pCtxRec->ctx_SegDs,
814 pCtxRec->ctx_SegEs,
815 pCtxRec->ctx_SegFs,
816 pCtxRec->ctx_SegGs));
817
818 if (pCtxRec->ContextFlags & CONTEXT_FLOATING_POINT) /* check flags */
819 {
820 ULONG ulCounter; /* temporary local counter for fp stack */
821
822 dprintf((" Env[0]=%08x Env[1]=%08x Env[2]=%08x Env[3]=%08x\n",
823 pCtxRec->ctx_env[0],
824 pCtxRec->ctx_env[1],
825 pCtxRec->ctx_env[2],
826 pCtxRec->ctx_env[3]));
827
828 dprintf((" Env[4]=%08x Env[5]=%08x Env[6]=%08x\n",
829 pCtxRec->ctx_env[4],
830 pCtxRec->ctx_env[5],
831 pCtxRec->ctx_env[6]));
832
833 for (ulCounter = 0;
834 ulCounter < 8; /* see TOOLKIT\INCLUDE\BSEEXPT.H, _CONTEXT structure */
835 ulCounter ++)
836 dprintf((" FP-Stack[%u] losig=%08x hisig=%08x signexp=%04x\n",
837 ulCounter,
838 pCtxRec->ctx_stack[0].losig,
839 pCtxRec->ctx_stack[0].hisig,
840 pCtxRec->ctx_stack[0].signexp));
841 }
842
843 dprintf(("---[End Of Exception Information]-----\n"));
844}
845
846
847/*****************************************************************************
848 * Name : ERR _System OS2ExceptionHandler
849 * Purpose :
850 * Parameters: ...
851 * Variables :
852 * Result :
853 * Remark :
854 * Status :
855 *
856 * Author : Patrick Haller [Tue, 1999/07/01 09:00]
857 *****************************************************************************/
858 /* from PPC DDK */
859#ifndef XCPT_CONTINUE_STOP
860#define XCPT_CONTINUE_STOP 0x00716668
861#endif
862
863ERR _System OS2ExceptionHandler(PEXCEPTIONREPORTRECORD pERepRec,
864 PEXCEPTIONREGISTRATIONRECORD pERegRec,
865 PCONTEXTRECORD pCtxRec,
866 PVOID p)
867{
868 // pERegRec->prev_structure = 0;
869 dprintfException(pERepRec, pERegRec, pCtxRec, p);
870
871 /* Access violation at a known location */
872 switch(pERepRec->ExceptionNum)
873 {
874 case XCPT_FLOAT_DENORMAL_OPERAND:
875 case XCPT_FLOAT_DIVIDE_BY_ZERO:
876 case XCPT_FLOAT_INEXACT_RESULT:
877 case XCPT_FLOAT_INVALID_OPERATION:
878 case XCPT_FLOAT_OVERFLOW:
879 case XCPT_FLOAT_STACK_CHECK:
880 case XCPT_FLOAT_UNDERFLOW:
881 dprintf(("KERNEL32: OS2ExceptionHandler: FPU exception, fix and continue\n"));
882 pCtxRec->ctx_env[0] |= 0x1F;
883 pCtxRec->ctx_stack[0].losig = 0;
884 pCtxRec->ctx_stack[0].hisig = 0;
885 pCtxRec->ctx_stack[0].signexp = 0;
886
887 return (ERR)(XCPT_CONTINUE_EXECUTION);
888
889 case XCPT_PROCESS_TERMINATE:
890 case XCPT_ASYNC_PROCESS_TERMINATE:
891 SetExceptionChain((ULONG)0);
892 return (XCPT_CONTINUE_SEARCH);
893
894 case XCPT_ACCESS_VIOLATION:
895 case XCPT_BREAKPOINT:
896 case XCPT_ARRAY_BOUNDS_EXCEEDED:
897 case XCPT_DATATYPE_MISALIGNMENT:
898 case XCPT_ILLEGAL_INSTRUCTION:
899 case XCPT_PRIVILEGED_INSTRUCTION:
900 case XCPT_INVALID_LOCK_SEQUENCE:
901 case XCPT_INTEGER_DIVIDE_BY_ZERO:
902 case XCPT_INTEGER_OVERFLOW:
903 case XCPT_SINGLE_STEP:
904 case XCPT_GUARD_PAGE_VIOLATION:
905 case XCPT_UNABLE_TO_GROW_STACK:
906 case XCPT_IN_PAGE_ERROR:
907 case XCPT_SIGNAL:
908 dprintf(("KERNEL32: OS2ExceptionHandler: Continue and kill\n"));
909 pCtxRec->ctx_RegEip = (ULONG)KillWin32Process;
910 pCtxRec->ctx_RegEsp = pCtxRec->ctx_RegEsp + 0x10;
911 pCtxRec->ctx_RegEax = pERepRec->ExceptionNum;
912 pCtxRec->ctx_RegEbx = pCtxRec->ctx_RegEip;
913 return (ERR)(XCPT_CONTINUE_EXECUTION);
914
915 default: //non-continuable exceptions
916 return (XCPT_CONTINUE_SEARCH);
917 }
918 return (XCPT_CONTINUE_SEARCH);
919}
920
921
922/*****************************************************************************
923 * Name : void ReplaceExceptionHandler
924 * Purpose :
925 * Parameters: ...
926 * Variables :
927 * Result :
928 * Remark :
929 * Status :
930 *
931 * Author : Sander van Leeuwen [Tue, 1999/07/01 09:00]
932 *****************************************************************************/
933
934//******************************************************************************
935//SvL: Replace original startup code exception handler
936extern BOOL fExeStarted;
937//******************************************************************************
938void ReplaceExceptionHandler()
939{
940 static BOOL fRegistered = FALSE;
941 PWINEXCEPTION_FRAME orgframe;
942 APIRET rc;
943 ULONGULONG timerval;
944
945 DisableFPUExceptions();
946
947 if(fExeStarted == FALSE)
948 return;
949
950 orgframe = QueryExceptionChain();
951 if((int)orgframe == 0 ||
952 (int)orgframe == -1)
953 return;
954
955 dprintf(("KERNEL32: ReplaceExceptionHandler\n"));
956
957 StartupCodeHandler = orgframe->Handler;
958 orgframe->Handler = (PEXCEPTION_HANDLER)OS2ExceptionHandler;
959 orgframe->Prev = (_WINEXCEPTION_FRAME *)0;
960 SetExceptionChain((ULONG)-1);
961
962#if 0
963 if(fRegistered == FALSE)
964 {
965#endif
966
967 dprintf(("KERNEL32: ReplaceExceptionHandler: New exception frame at %X\n",
968 orgframe));
969 rc = DosSetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD)orgframe);
970 fRegistered = TRUE;
971
972#if 0
973 }
974 else
975 {
976 while(orgframe && orgframe->Handler != (PEXCEPTION_HANDLER)OS2ExceptionHandler)
977 {
978 orgframe = orgframe->Prev;
979 }
980
981 dprintf(("KERNEL32: ReplaceExceptionHandler: Restore old exception frame %X\n",
982 orgframe));
983 if(orgframe)
984 {
985 orgframe->Prev = (_WINEXCEPTION_FRAME *)0;
986 SetExceptionChain((ULONG)orgframe);
987 }
988 }
989#endif
990}
991
Note: See TracBrowser for help on using the repository browser.