Changeset 10921


Ignore:
Timestamp:
Sep 30, 2008, 11:07:45 AM (11 years ago)
Author:
gb
Message:

In windows_arbstack_exception_handler: insist that we're running on
some stack other than the C stack when the exception occurs (in general,
we aren't going to be able to do much about exceptions that happen on
the C stack, anyway.) Always build a (copy of) the exception context/
info on the foreign stack; don't switch to the foreign stack from the
handler, but setup the exception context we were called with to enter
the higher-level exception handler when it's resumed, and tell the OS
to resume execution. (While we're at it, arrange that the higher-level
handler gets the TCR as an argument, to avoid having to look it up again.)

This allows the Windows runtime to clean up after itself after
returning from the low-level handler (releasing locks, etc.), and has
the effect of calling our higher-level handler on the foreign stack
with a copy of the original exception context/info.

(If there was ever any reason to, we could do the stack switch the
same way on other platforms. On non-Mach systems, I think that the
handler is called directly from the kernel and on Darwin we generally
fake things using Mach exception-handling futilities, so there doesn't
seem to be any need for this elsewhere.)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/lisp-kernel/x86-exceptions.c

    r10891 r10921  
    17471747
    17481748LONG
    1749 windows_exception_handler(EXCEPTION_POINTERS *exception_pointers)
    1750 {
    1751   TCR *tcr = get_tcr(false);
     1749windows_exception_handler(EXCEPTION_POINTERS *exception_pointers, TCR *tcr)
     1750{
    17521751  DWORD code = exception_pointers->ExceptionRecord->ExceptionCode;
    17531752  int old_valence, signal_number;
     
    17751774}
    17761775
    1777 LONG windows_switch_to_foreign_stack(LispObj, void*, void*);
    1778 
    1779 LONG
    1780 handle_windows_exception_on_foreign_stack(TCR *tcr,
    1781                                           CONTEXT *context,
    1782                                           void *handler,
    1783                                           EXCEPTION_POINTERS *original_ep)
     1776void
     1777setup_exception_handler_call(CONTEXT *context,
     1778                             LispObj new_sp,
     1779                             void *handler,
     1780                             EXCEPTION_POINTERS *new_ep,
     1781                             TCR *tcr)
     1782{
     1783  extern void windows_halt(void);
     1784  LispObj *p = (LispObj *)new_sp;
     1785#ifdef WIN_64
     1786  p-=4;                         /* win64 abi argsave nonsense */
     1787  *(--p) = (LispObj)windows_halt;
     1788  context->Rsp = (DWORD64)p;
     1789  context->Rip = (DWORD64)handler;
     1790  context->Rcx = (DWORD64)new_ep;
     1791  context->Rdx = (DWORD64)tcr;
     1792#else
     1793  p-=4;                          /* args on stack, stack aligned */
     1794  p[0] = (LispObj)new_ep;
     1795  p[1] = (LispObj)tcr;
     1796  *(--p) = (LispObj)windows_halt;
     1797  context->Esp = (DWORD)p;
     1798  context->Eip = (DWORD)handler;
     1799#endif
     1800}
     1801
     1802void
     1803prepare_to_handle_windows_exception_on_foreign_stack(TCR *tcr,
     1804                                                     CONTEXT *context,
     1805                                                     void *handler,
     1806                                                     EXCEPTION_POINTERS *original_ep)
    17841807{
    17851808  LispObj foreign_rsp =
     
    17991822  new_ep->ContextRecord = new_context;
    18001823  new_ep->ExceptionRecord = new_info;
    1801   return windows_switch_to_foreign_stack(foreign_rsp,handler,new_ep);
     1824  setup_exception_handler_call(context,foreign_rsp,handler,new_ep, tcr);
    18021825}
    18031826
     
    18111834  } else {
    18121835    TCR *tcr = get_interrupt_tcr(false);
    1813     area *vs = tcr->vs_area;
     1836    area *cs = tcr->cs_area;
    18141837    BytePtr current_sp = (BytePtr) current_stack_pointer();
    1815     struct _TEB *teb = NtCurrentTeb();
     1838    CONTEXT *context = exception_pointers->ContextRecord;
    18161839   
    1817     if ((current_sp >= vs->low) &&
    1818         (current_sp < vs->high)) {
    1819       return
    1820         handle_windows_exception_on_foreign_stack(tcr,
    1821                                                   exception_pointers->ContextRecord,
    1822                                                   windows_exception_handler,
    1823                                                   exception_pointers);
    1824     }
    1825     return windows_exception_handler(exception_pointers);
     1840    if ((current_sp >= cs->low) &&
     1841        (current_sp < cs->high)) {
     1842      FBug(context, "Exception on foreign stack\n");
     1843    }
     1844
     1845    prepare_to_handle_windows_exception_on_foreign_stack(tcr,
     1846                                                         context,
     1847                                                         windows_exception_handler,
     1848                                                         exception_pointers);
     1849    return EXCEPTION_CONTINUE_EXECUTION;
    18261850  }
    18271851}
Note: See TracChangeset for help on using the changeset viewer.