(_cygtls::andreas): Convert to a pointer.
(san): Convert to a real class with methods. Use a linked list to keep track
of previous handlers on the "stack".
(myfault): Rewrite to use new san class rather than calling directly into
_cygtls.
* cygtls.cc (_cygtls::init_exception_handler): Just assume that we're always
using the standard exception handler.
(_cygtls::init_thread): Reflect loss of argument to init_exception_handler.
* dcrt0.cc (dll_crt0_1): Ditto.
* dfcn.cc (dlopen): Ditto.
(dlclose): Reset the exception handler after FreeLibrary.
* dll_init.cc (dll_list::detach): Make sure that the exception handler is
initialized before calling destructors.
* exceptions.cc (_cygtls::handle_exceptions): Accommodate new andreas pointer.
* thread.cc (verifyable_object_isvalid): Pass objectptr to faulted for explicit
NULL pointer checking.
* tlsoffsets.h: Regenerate.
+2010-02-26 Christopher Faylor <me+cygwin@cgf.cx>
+
+ * cygtls.h (_cygtls::init_exception_handler): Eliminate argument.
+ (_cygtls::andreas): Convert to a pointer.
+ (san): Convert to a real class with methods. Use a linked list to
+ keep track of previous handlers on the "stack".
+ (myfault): Rewrite to use new san class rather than calling directly
+ into _cygtls.
+ * cygtls.cc (_cygtls::init_exception_handler): Just assume that we're
+ always using the standard exception handler.
+ (_cygtls::init_thread): Reflect loss of argument to
+ init_exception_handler.
+ * dcrt0.cc (dll_crt0_1): Ditto.
+ * dfcn.cc (dlopen): Ditto.
+ (dlclose): Reset the exception handler after FreeLibrary.
+ * dll_init.cc (dll_list::detach): Make sure that the exception handler
+ is initialized before calling destructors.
+ * exceptions.cc (_cygtls::handle_exceptions): Accommodate new andreas
+ pointer.
+ * thread.cc (verifyable_object_isvalid): Pass objectptr to faulted for
+ explicit NULL pointer checking.
+ * tlsoffsets.h: Regenerate.
+
2010-02-26 Christopher Faylor <me+cygwin@cgf.cx>
* mkimport: cd away from temp directory or Windows will have problems
locals.process_logmask = LOG_UPTO (LOG_DEBUG);
/* Initialize this thread's ability to respond to things like
SIGSEGV or SIGFPE. */
- init_exception_handler (handle_exceptions);
+ init_exception_handler ();
}
thread_id = GetCurrentThreadId ();
extern exception_list *_except_list asm ("%fs:0");
void
-_cygtls::init_exception_handler (exception_handler *eh)
+_cygtls::init_exception_handler ()
{
/* Here in the distant past of 17-Jul-2009, we had an issue where Windows
2008 became YA perplexed because the cygwin exception handler was added
the old exception handler from the list and add it to the beginning.
The next step will probably be to call this function at various points
- in cygwin (like from _cygtls::setup_fault maybe) to absoltely ensure that
+ in cygwin (like from _cygtls::setup_fault maybe) to absolutely ensure that
we have control. For now, however, this seems good enough.
(cgf 2010-02-23)
*/
Windows 2008, which irremediably gets into an endless loop, taking 100%
CPU. That's why we reverted to a normal SEH chain and changed the way
the exception handler returns to the application. */
- el.handler = eh;
+ el.handler = handle_exceptions;
el.prev = _except_list;
_except_list = ⪙
}
void destroy ();
friend class tmp_pathbuf;
friend class _cygtls;
+ friend class san;
};
class unionent
HANDLE thread_ev;
} waitq;
-typedef struct
-{
- void *_myfault;
- int _myfault_errno;
- int _myfault_c_cnt;
- int _myfault_w_cnt;
-} san;
-
/* Changes to the below structure may require acompanying changes to the very
simple parser in the perl script 'gentls_offsets' (<<-- start parsing here).
The union in this structure is used to force alignment between the version
};
struct _local_storage locals;
class cygthread *_ctinfo;
- san andreas;
+ class san *andreas;
waitq wq;
int sig;
unsigned incyg;
/* exception handling */
static int handle_exceptions (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *);
bool inside_kernel (CONTEXT *);
- void init_exception_handler (int (*) (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void*));
+ void init_exception_handler () __attribute__ ((regparm(1)));
void signal_exit (int) __attribute__ ((noreturn, regparm(2)));
void copy_context (CONTEXT *) __attribute__ ((regparm(2)));
void signal_debugger (int) __attribute__ ((regparm(2)));
void lock () __attribute__ ((regparm (1)));
void unlock () __attribute__ ((regparm (1)));
bool locked () __attribute__ ((regparm (1)));
- void*& fault_guarded () {return andreas._myfault;}
- void return_from_fault ()
- {
- if (andreas._myfault_errno)
- set_errno (andreas._myfault_errno);
- /* Restore tls_pathbuf counters in case of error. */
- locals.pathbufs.c_cnt = andreas._myfault_c_cnt;
- locals.pathbufs.w_cnt = andreas._myfault_w_cnt;
- __ljfault ((int *) andreas._myfault, 1);
- }
- int setup_fault (jmp_buf j, san& old_j, int myerrno) __attribute__ ((always_inline))
- {
- old_j._myfault = andreas._myfault;
- old_j._myfault_errno = andreas._myfault_errno;
- old_j._myfault_c_cnt = andreas._myfault_c_cnt;
- old_j._myfault_w_cnt = andreas._myfault_w_cnt;
- andreas._myfault = (void *) j;
- andreas._myfault_errno = myerrno;
- /* Save tls_pathbuf counters. */
- andreas._myfault_c_cnt = locals.pathbufs.c_cnt;
- andreas._myfault_w_cnt = locals.pathbufs.w_cnt;
- return __sjfault (j);
- }
- void reset_fault (san& old_j) __attribute__ ((always_inline))
- {
- andreas._myfault = old_j._myfault;
- andreas._myfault_errno = old_j._myfault_errno;
- }
/*gentls_offsets*/
};
#pragma pack(pop)
extern _cygtls *_main_tls;
extern _cygtls *_sig_tls;
+class san
+{
+ san *_clemente;
+ jmp_buf _context;
+ int _errno;
+ int _c_cnt;
+ int _w_cnt;
+public:
+ int setup (int myerrno = 0) __attribute__ ((always_inline))
+ {
+ _clemente = _my_tls.andreas;
+ _my_tls.andreas = this;
+ _errno = myerrno;
+ _c_cnt = _my_tls.locals.pathbufs.c_cnt;
+ _w_cnt = _my_tls.locals.pathbufs.w_cnt;
+ return __sjfault (_context);
+ }
+ void leave () __attribute__ ((always_inline))
+ {
+ if (_errno)
+ set_errno (_errno);
+ /* Restore tls_pathbuf counters in case of error. */
+ _my_tls.locals.pathbufs.c_cnt = _c_cnt;
+ _my_tls.locals.pathbufs.w_cnt = _w_cnt;
+ __ljfault (_context, 1);
+ }
+ void reset () __attribute__ ((always_inline))
+ {
+ _my_tls.andreas = _clemente;
+ }
+};
+
class myfault
{
- jmp_buf buf;
san sebastian;
public:
- ~myfault () __attribute__ ((always_inline)) { _my_tls.reset_fault (sebastian); }
- inline int faulted (int myerrno = 0) __attribute__ ((always_inline))
+ ~myfault () __attribute__ ((always_inline)) { sebastian.reset (); }
+ inline int faulted () __attribute__ ((always_inline))
+ {
+ return sebastian.setup (0);
+ }
+ inline int faulted (void const *obj, int myerrno = 0) __attribute__ ((always_inline))
+ {
+ return (!obj || !(*(const char **)obj)) || sebastian.setup (myerrno);
+ }
+ inline int faulted (int myerrno) __attribute__ ((always_inline))
{
- return _my_tls.setup_fault (buf, sebastian, myerrno);
+ return sebastian.setup (myerrno);
}
};
{
_tlsbase = (char *) fork_info->stackbottom;
_tlstop = (char *) fork_info->stacktop;
- _my_tls.init_exception_handler (_cygtls::handle_exceptions);
+ _my_tls.init_exception_handler ();
}
longjmp (fork_info->jmp, true);
ret = (void *) LoadLibraryW (path);
/* In case it was removed by LoadLibrary. */
- _my_tls.init_exception_handler (_cygtls::handle_exceptions);
+ _my_tls.init_exception_handler ();
/* Restore original cxx_malloc pointer. */
__cygwin_user_data.cxx_malloc = tmp_malloc;
int
dlclose (void *handle)
{
- int ret = -1;
- if (handle == GetModuleHandle (NULL) || FreeLibrary ((HMODULE) handle))
+ int ret;
+ if (handle == GetModuleHandle (NULL))
ret = 0;
+ else
+ {
+ if (FreeLibrary ((HMODULE) handle))
+ ret = 0;
+ else
+ ret = -1;
+ /* In case it was removed by FreeLibrary */
+ _my_tls.init_exception_handler ();
+ }
if (ret)
set_dl_error ("dlclose");
return ret;
system_printf ("WARNING: trying to detach an already detached dll ...");
if (--d->count == 0)
{
+ /* Make sure our exception handler is enabled for destructors */
+ _my_tls.init_exception_handler ();
__cxa_finalize (d);
d->run_dtors ();
d->prev->next = d->next;
the exception handler should be guaranteed to be installed.
I'm leaving it in until potentially after the release of
1.7.1 */
- _my_tls.init_exception_handler (_cygtls::handle_exceptions);
+ _my_tls.init_exception_handler ();
if (p == NULL)
p = &__cygwin_user_data;
break;
}
- if (me.fault_guarded ())
- me.return_from_fault ();
+ if (me.andreas)
+ me.andreas->leave (); /* Return from a "san" caught fault */
me.copy_context (in);
void *static_ptr2, void *static_ptr3)
{
myfault efault;
- /* Check for NULL pointer specifically since it is a cheap test and avoids the
- overhead of setting up the fault handler. */
- if (!objectptr || efault.faulted ())
+ if (efault.faulted (objectptr))
return INVALID_OBJECT;
verifyable_object **object = (verifyable_object **) objectptr;
//;# autogenerated: Do not edit.
-//; $tls::sizeof__cygtls = 4324;
+//; $tls::sizeof__cygtls = 4312;
//; $tls::func = -12700;
//; $tls::pfunc = 0;
//; $tls::el = -12696;
//; $tls::p_ctinfo = 3228;
//; $tls::andreas = -9468;
//; $tls::pandreas = 3232;
-//; $tls::wq = -9452;
-//; $tls::pwq = 3248;
-//; $tls::sig = -9424;
-//; $tls::psig = 3276;
-//; $tls::incyg = -9420;
-//; $tls::pincyg = 3280;
-//; $tls::spinning = -9416;
-//; $tls::pspinning = 3284;
-//; $tls::stacklock = -9412;
-//; $tls::pstacklock = 3288;
-//; $tls::stackptr = -9408;
-//; $tls::pstackptr = 3292;
-//; $tls::stack = -9404;
-//; $tls::pstack = 3296;
-//; $tls::initialized = -8380;
-//; $tls::pinitialized = 4320;
+//; $tls::wq = -9464;
+//; $tls::pwq = 3236;
+//; $tls::sig = -9436;
+//; $tls::psig = 3264;
+//; $tls::incyg = -9432;
+//; $tls::pincyg = 3268;
+//; $tls::spinning = -9428;
+//; $tls::pspinning = 3272;
+//; $tls::stacklock = -9424;
+//; $tls::pstacklock = 3276;
+//; $tls::stackptr = -9420;
+//; $tls::pstackptr = 3280;
+//; $tls::stack = -9416;
+//; $tls::pstack = 3284;
+//; $tls::initialized = -8392;
+//; $tls::pinitialized = 4308;
//; __DATA__
#define tls_func (-12700)
#define tls_p_ctinfo (3228)
#define tls_andreas (-9468)
#define tls_pandreas (3232)
-#define tls_wq (-9452)
-#define tls_pwq (3248)
-#define tls_sig (-9424)
-#define tls_psig (3276)
-#define tls_incyg (-9420)
-#define tls_pincyg (3280)
-#define tls_spinning (-9416)
-#define tls_pspinning (3284)
-#define tls_stacklock (-9412)
-#define tls_pstacklock (3288)
-#define tls_stackptr (-9408)
-#define tls_pstackptr (3292)
-#define tls_stack (-9404)
-#define tls_pstack (3296)
-#define tls_initialized (-8380)
-#define tls_pinitialized (4320)
+#define tls_wq (-9464)
+#define tls_pwq (3236)
+#define tls_sig (-9436)
+#define tls_psig (3264)
+#define tls_incyg (-9432)
+#define tls_pincyg (3268)
+#define tls_spinning (-9428)
+#define tls_pspinning (3272)
+#define tls_stacklock (-9424)
+#define tls_pstacklock (3276)
+#define tls_stackptr (-9420)
+#define tls_pstackptr (3280)
+#define tls_stack (-9416)
+#define tls_pstack (3284)
+#define tls_initialized (-8392)
+#define tls_pinitialized (4308)