diff options
Diffstat (limited to 'winsup/cygwin/exception.h')
-rw-r--r-- | winsup/cygwin/exception.h | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/winsup/cygwin/exception.h b/winsup/cygwin/exception.h index c14aa1614..5b11b0c00 100644 --- a/winsup/cygwin/exception.h +++ b/winsup/cygwin/exception.h @@ -8,35 +8,61 @@ details. */ #pragma once +#ifdef __x86_64__ +#define _exception_list _EXCEPTION_REGISTRATION_RECORD +#endif + #include <exceptions.h> +#ifndef __x86_64__ extern exception_list *_except_list asm ("%fs:0"); +#endif class exception { +#ifdef __x86_64__ + static bool handler_installed; + static int handle (LPEXCEPTION_POINTERS); +#else exception_list el; exception_list *save; static int handle (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *); +#endif public: exception () __attribute__ ((always_inline)) { +#ifdef __x86_64__ + if (!handler_installed) + { + handler_installed = true; + /* The unhandled exception filter goes first. It won't work if the + executable is debugged, but then the vectored continue handler + kicks in. For some reason the vectored continue handler doesn't + get called if no unhandled exception filter is installed. */ + SetUnhandledExceptionFilter (handle); + AddVectoredContinueHandler (1, handle); + } +#else save = _except_list; el.handler = handle; el.prev = _except_list; _except_list = ⪙ +#endif }; +#ifndef __x86_64__ ~exception () __attribute__ ((always_inline)) { _except_list = save; } +#endif }; class cygwin_exception { - DWORD ebp; + PUINT_PTR framep; PCONTEXT ctx; EXCEPTION_RECORD *e; void dump_exception (); public: - cygwin_exception (DWORD in_ebp, PCONTEXT in_ctx = NULL, EXCEPTION_RECORD *in_e = NULL): - ebp (in_ebp), ctx (in_ctx), e (in_e) {} + cygwin_exception (PUINT_PTR in_framep, PCONTEXT in_ctx = NULL, EXCEPTION_RECORD *in_e = NULL): + framep (in_framep), ctx (in_ctx), e (in_e) {} void dumpstack (); PCONTEXT context () const {return ctx;} }; |