Ignore:
Timestamp:
Oct 8, 1999, 9:47:26 PM (26 years ago)
Author:
sandervl
Message:

Ported latest Wine exception handling code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/exceptions.cpp

    r1137 r1200  
    1 /* $Id: exceptions.cpp,v 1.20 1999-10-05 14:28:33 sandervl Exp $ */
     1/* $Id: exceptions.cpp,v 1.21 1999-10-08 19:47:26 sandervl Exp $ */
    22
    33/*
     
    1111 * Project Odin Software License can be found in LICENSE.TXT
    1212 *
     13 *
     14 * (dlls\ntdll\exception.c)
     15 *
     16 * Copyright 1999 Turchanov Sergey
     17 * Copyright 1999 Alexandre Julliard
    1318 *
    1419 * (win32\except.c)
     
    5863#include <misc.h>
    5964#include "mmap.h"
     65#include <wprocess.h>
    6066
    6167//Global Process Unhandled exception filter
     
    112118 * Author    : Sander van Leeuwen [Tue, 1999/07/01 09:00]
    113119 *****************************************************************************/
     120
     121void WIN32API RtlRaiseException(WINEXCEPTION_RECORD *rec, WINCONTEXT *context);
    114122
    115123VOID _Pascal OS2RaiseException(DWORD dwExceptionCode,
     
    122130                               DWORD es,  DWORD fs,   DWORD gs,  DWORD ss)
    123131{
    124   PWINEXCEPTION_FRAME   pframe;
     132  PWINEXCEPTION_FRAME   pframe, dispatch, nested_frame;
    125133  WINEXCEPTION_RECORD   record;
     134  WINEXCEPTION_RECORD   newrec;
    126135  WINEXCEPTION_POINTERS ExceptionInfo;
    127136  WINCONTEXT            context;
    128   DWORD                 dispatch;
    129137  int                   rc;
    130138  int                   i;
     
    169177  // get chain of exception frames
    170178  rc     = ExceptionContinueSearch;
    171   pframe = QueryExceptionChain();
     179
     180  nested_frame = NULL;
     181  TEB *winteb = GetThreadTEB();
     182  pframe      = (PWINEXCEPTION_FRAME)winteb->except;
    172183
    173184  // walk the exception chain
    174185  while( (pframe != NULL) && (pframe != ((void *)0xFFFFFFFF)) )
    175186  {
    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;
     187        dispatch=0;
     188
     189        dprintf(("Calling exception handler %x", pframe->Handler));
     190        /* Check frame address */
     191        if (((void*)pframe < winteb->stack_low) ||
     192            ((void*)(pframe+1) > winteb->stack_top) ||
     193            (int)pframe & 3)
     194        {
     195            record.ExceptionFlags |= EH_STACK_INVALID;
     196            break;
     197        }
     198
     199        rc = pframe->Handler(&record,
     200                             pframe,
     201                             &context,
     202                             &dispatch);
     203
     204        if (pframe == nested_frame)
     205        {
     206            /* no longer nested */
     207            nested_frame = NULL;
     208            record.ExceptionFlags &= ~EH_NESTED_CALL;
     209        }
     210
     211        dprintf(("exception handler returned %x", rc));
     212
     213        switch(rc)
     214        {
     215        case ExceptionContinueExecution:
     216            if (!(record.ExceptionFlags & EH_NONCONTINUABLE)) return;
     217            DosExit(EXIT_PROCESS, 0);
     218            break;
     219        case ExceptionContinueSearch:
     220            break;
     221        case ExceptionNestedException:
     222            if (nested_frame < dispatch) nested_frame = dispatch;
     223            record.ExceptionFlags |= EH_NESTED_CALL;
     224            break;
     225        default:
     226            DosExit(EXIT_PROCESS, 0);
     227            break;
     228        }
     229
     230        pframe = pframe->Prev;
    185231  }
    186232
     
    226272                         DWORD es,  DWORD fs,   DWORD gs,  DWORD ss)
    227273{
    228   WINEXCEPTION_RECORD record;
     274  PWINEXCEPTION_FRAME frame, dispatch;
     275  WINEXCEPTION_RECORD record, newrec;
    229276  WINCONTEXT          context;
    230   DWORD               dispatch;
    231277  int                 rc;
    232278
     
    267313
    268314  /* 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);
     315  TEB *winteb = GetThreadTEB();
     316  frame       = (PWINEXCEPTION_FRAME)winteb->except;
     317
     318  while ((frame != (PWINEXCEPTION_FRAME)0xffffffff) && (frame != pEndFrame))
     319  {
     320        /* Check frame address */
     321        if (pEndFrame && (frame > pEndFrame))
     322        {
     323            newrec.ExceptionCode    = STATUS_INVALID_UNWIND_TARGET;
     324            newrec.ExceptionFlags   = EH_NONCONTINUABLE;
     325            newrec.ExceptionRecord  = pRecord;
     326            newrec.NumberParameters = 0;
     327            dprintf(("KERNEL32: RtlUnwind terminating thread.\n"));
     328            DosExit(EXIT_THREAD, 0);
     329        }
     330        if (((void*)frame < winteb->stack_low) ||
     331            ((void*)(frame+1) > winteb->stack_top) ||
     332            (int)frame & 3)
     333        {
     334            newrec.ExceptionCode    = STATUS_BAD_STACK;
     335            newrec.ExceptionFlags   = EH_NONCONTINUABLE;
     336            newrec.ExceptionRecord  = pRecord;
     337            newrec.NumberParameters = 0;
     338            dprintf(("KERNEL32: RtlUnwind terminating thread.\n"));
     339            DosExit(EXIT_THREAD, 0);
     340        }
     341
     342        /* Call handler */
     343        dprintf(("Calling exception handler %x", frame->Handler));
     344        switch(frame->Handler(pRecord, frame, &context, &dispatch ))
     345        {
     346        case ExceptionContinueSearch:
     347            break;
     348        case ExceptionCollidedUnwind:
     349            frame = dispatch;
     350            break;
     351        default:
     352            newrec.ExceptionCode    = STATUS_INVALID_DISPOSITION;
     353            newrec.ExceptionFlags   = EH_NONCONTINUABLE;
     354            newrec.ExceptionRecord  = pRecord;
     355            newrec.NumberParameters = 0;
     356            dprintf(("KERNEL32: RtlUnwind terminating thread.\n"));
     357            DosExit(EXIT_THREAD, 0);
     358            break;
     359        }
     360        SetExceptionChain((DWORD)frame->Prev);
     361        frame = frame->Prev;
    296362  }
    297363  return(0);
Note: See TracChangeset for help on using the changeset viewer.