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

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

Implemented multiple views of memory mapped files + some bugfixes to PE loader code

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