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

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

Fix: removed the beep from the exception message box. You might get a infinite beeeeeeeep on killing such a process (XAB - extremely annoying behaviour)

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