* 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.
This commit is contained in:
parent
b6336c95b4
commit
d5d5bf4dd5
|
@ -1,3 +1,26 @@
|
||||||
|
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>
|
2010-02-26 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
* mkimport: cd away from temp directory or Windows will have problems
|
* mkimport: cd away from temp directory or Windows will have problems
|
||||||
|
|
|
@ -91,7 +91,7 @@ _cygtls::init_thread (void *x, DWORD (*func) (void *, void *))
|
||||||
locals.process_logmask = LOG_UPTO (LOG_DEBUG);
|
locals.process_logmask = LOG_UPTO (LOG_DEBUG);
|
||||||
/* Initialize this thread's ability to respond to things like
|
/* Initialize this thread's ability to respond to things like
|
||||||
SIGSEGV or SIGFPE. */
|
SIGSEGV or SIGFPE. */
|
||||||
init_exception_handler (handle_exceptions);
|
init_exception_handler ();
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_id = GetCurrentThreadId ();
|
thread_id = GetCurrentThreadId ();
|
||||||
|
@ -226,7 +226,7 @@ _cygtls::set_siginfo (sigpacket *pack)
|
||||||
extern exception_list *_except_list asm ("%fs:0");
|
extern exception_list *_except_list asm ("%fs:0");
|
||||||
|
|
||||||
void
|
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
|
/* 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
|
2008 became YA perplexed because the cygwin exception handler was added
|
||||||
|
@ -249,7 +249,7 @@ _cygtls::init_exception_handler (exception_handler *eh)
|
||||||
the old exception handler from the list and add it to the beginning.
|
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
|
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.
|
we have control. For now, however, this seems good enough.
|
||||||
(cgf 2010-02-23)
|
(cgf 2010-02-23)
|
||||||
*/
|
*/
|
||||||
|
@ -275,7 +275,7 @@ _cygtls::init_exception_handler (exception_handler *eh)
|
||||||
Windows 2008, which irremediably gets into an endless loop, taking 100%
|
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
|
CPU. That's why we reverted to a normal SEH chain and changed the way
|
||||||
the exception handler returns to the application. */
|
the exception handler returns to the application. */
|
||||||
el.handler = eh;
|
el.handler = handle_exceptions;
|
||||||
el.prev = _except_list;
|
el.prev = _except_list;
|
||||||
_except_list = ⪙
|
_except_list = ⪙
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ public:
|
||||||
void destroy ();
|
void destroy ();
|
||||||
friend class tmp_pathbuf;
|
friend class tmp_pathbuf;
|
||||||
friend class _cygtls;
|
friend class _cygtls;
|
||||||
|
friend class san;
|
||||||
};
|
};
|
||||||
|
|
||||||
class unionent
|
class unionent
|
||||||
|
@ -157,14 +158,6 @@ typedef struct struct_waitq
|
||||||
HANDLE thread_ev;
|
HANDLE thread_ev;
|
||||||
} waitq;
|
} 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
|
/* Changes to the below structure may require acompanying changes to the very
|
||||||
simple parser in the perl script 'gentls_offsets' (<<-- start parsing here).
|
simple parser in the perl script 'gentls_offsets' (<<-- start parsing here).
|
||||||
The union in this structure is used to force alignment between the version
|
The union in this structure is used to force alignment between the version
|
||||||
|
@ -205,7 +198,7 @@ struct _cygtls
|
||||||
};
|
};
|
||||||
struct _local_storage locals;
|
struct _local_storage locals;
|
||||||
class cygthread *_ctinfo;
|
class cygthread *_ctinfo;
|
||||||
san andreas;
|
class san *andreas;
|
||||||
waitq wq;
|
waitq wq;
|
||||||
int sig;
|
int sig;
|
||||||
unsigned incyg;
|
unsigned incyg;
|
||||||
|
@ -239,7 +232,7 @@ struct _cygtls
|
||||||
/* exception handling */
|
/* exception handling */
|
||||||
static int handle_exceptions (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *);
|
static int handle_exceptions (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *);
|
||||||
bool inside_kernel (CONTEXT *);
|
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 signal_exit (int) __attribute__ ((noreturn, regparm(2)));
|
||||||
void copy_context (CONTEXT *) __attribute__ ((regparm(2)));
|
void copy_context (CONTEXT *) __attribute__ ((regparm(2)));
|
||||||
void signal_debugger (int) __attribute__ ((regparm(2)));
|
void signal_debugger (int) __attribute__ ((regparm(2)));
|
||||||
|
@ -256,34 +249,6 @@ struct _cygtls
|
||||||
void lock () __attribute__ ((regparm (1)));
|
void lock () __attribute__ ((regparm (1)));
|
||||||
void unlock () __attribute__ ((regparm (1)));
|
void unlock () __attribute__ ((regparm (1)));
|
||||||
bool locked () __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*/
|
/*gentls_offsets*/
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
@ -298,15 +263,54 @@ extern char *_tlstop __asm__ ("%fs:8");
|
||||||
extern _cygtls *_main_tls;
|
extern _cygtls *_main_tls;
|
||||||
extern _cygtls *_sig_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
|
class myfault
|
||||||
{
|
{
|
||||||
jmp_buf buf;
|
|
||||||
san sebastian;
|
san sebastian;
|
||||||
public:
|
public:
|
||||||
~myfault () __attribute__ ((always_inline)) { _my_tls.reset_fault (sebastian); }
|
~myfault () __attribute__ ((always_inline)) { sebastian.reset (); }
|
||||||
inline int faulted (int myerrno = 0) __attribute__ ((always_inline))
|
inline int faulted () __attribute__ ((always_inline))
|
||||||
{
|
{
|
||||||
return _my_tls.setup_fault (buf, sebastian, myerrno);
|
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 sebastian.setup (myerrno);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -823,7 +823,7 @@ dll_crt0_1 (void *)
|
||||||
{
|
{
|
||||||
_tlsbase = (char *) fork_info->stackbottom;
|
_tlsbase = (char *) fork_info->stackbottom;
|
||||||
_tlstop = (char *) fork_info->stacktop;
|
_tlstop = (char *) fork_info->stacktop;
|
||||||
_my_tls.init_exception_handler (_cygtls::handle_exceptions);
|
_my_tls.init_exception_handler ();
|
||||||
}
|
}
|
||||||
|
|
||||||
longjmp (fork_info->jmp, true);
|
longjmp (fork_info->jmp, true);
|
||||||
|
|
|
@ -110,7 +110,7 @@ dlopen (const char *name, int)
|
||||||
ret = (void *) LoadLibraryW (path);
|
ret = (void *) LoadLibraryW (path);
|
||||||
|
|
||||||
/* In case it was removed by LoadLibrary. */
|
/* 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. */
|
/* Restore original cxx_malloc pointer. */
|
||||||
__cygwin_user_data.cxx_malloc = tmp_malloc;
|
__cygwin_user_data.cxx_malloc = tmp_malloc;
|
||||||
|
@ -160,9 +160,18 @@ dlsym (void *handle, const char *name)
|
||||||
int
|
int
|
||||||
dlclose (void *handle)
|
dlclose (void *handle)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret;
|
||||||
if (handle == GetModuleHandle (NULL) || FreeLibrary ((HMODULE) handle))
|
if (handle == GetModuleHandle (NULL))
|
||||||
ret = 0;
|
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)
|
if (ret)
|
||||||
set_dl_error ("dlclose");
|
set_dl_error ("dlclose");
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -169,6 +169,8 @@ dll_list::detach (void *retaddr)
|
||||||
system_printf ("WARNING: trying to detach an already detached dll ...");
|
system_printf ("WARNING: trying to detach an already detached dll ...");
|
||||||
if (--d->count == 0)
|
if (--d->count == 0)
|
||||||
{
|
{
|
||||||
|
/* Make sure our exception handler is enabled for destructors */
|
||||||
|
_my_tls.init_exception_handler ();
|
||||||
__cxa_finalize (d);
|
__cxa_finalize (d);
|
||||||
d->run_dtors ();
|
d->run_dtors ();
|
||||||
d->prev->next = d->next;
|
d->prev->next = d->next;
|
||||||
|
@ -329,7 +331,7 @@ dll_dllcrt0_1 (VOID *x)
|
||||||
the exception handler should be guaranteed to be installed.
|
the exception handler should be guaranteed to be installed.
|
||||||
I'm leaving it in until potentially after the release of
|
I'm leaving it in until potentially after the release of
|
||||||
1.7.1 */
|
1.7.1 */
|
||||||
_my_tls.init_exception_handler (_cygtls::handle_exceptions);
|
_my_tls.init_exception_handler ();
|
||||||
|
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
p = &__cygwin_user_data;
|
p = &__cygwin_user_data;
|
||||||
|
|
|
@ -622,8 +622,8 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (me.fault_guarded ())
|
if (me.andreas)
|
||||||
me.return_from_fault ();
|
me.andreas->leave (); /* Return from a "san" caught fault */
|
||||||
|
|
||||||
me.copy_context (in);
|
me.copy_context (in);
|
||||||
|
|
||||||
|
|
|
@ -124,9 +124,7 @@ verifyable_object_isvalid (void const *objectptr, thread_magic_t magic, void *st
|
||||||
void *static_ptr2, void *static_ptr3)
|
void *static_ptr2, void *static_ptr3)
|
||||||
{
|
{
|
||||||
myfault efault;
|
myfault efault;
|
||||||
/* Check for NULL pointer specifically since it is a cheap test and avoids the
|
if (efault.faulted (objectptr))
|
||||||
overhead of setting up the fault handler. */
|
|
||||||
if (!objectptr || efault.faulted ())
|
|
||||||
return INVALID_OBJECT;
|
return INVALID_OBJECT;
|
||||||
|
|
||||||
verifyable_object **object = (verifyable_object **) objectptr;
|
verifyable_object **object = (verifyable_object **) objectptr;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//;# autogenerated: Do not edit.
|
//;# autogenerated: Do not edit.
|
||||||
|
|
||||||
//; $tls::sizeof__cygtls = 4324;
|
//; $tls::sizeof__cygtls = 4312;
|
||||||
//; $tls::func = -12700;
|
//; $tls::func = -12700;
|
||||||
//; $tls::pfunc = 0;
|
//; $tls::pfunc = 0;
|
||||||
//; $tls::el = -12696;
|
//; $tls::el = -12696;
|
||||||
|
@ -43,22 +43,22 @@
|
||||||
//; $tls::p_ctinfo = 3228;
|
//; $tls::p_ctinfo = 3228;
|
||||||
//; $tls::andreas = -9468;
|
//; $tls::andreas = -9468;
|
||||||
//; $tls::pandreas = 3232;
|
//; $tls::pandreas = 3232;
|
||||||
//; $tls::wq = -9452;
|
//; $tls::wq = -9464;
|
||||||
//; $tls::pwq = 3248;
|
//; $tls::pwq = 3236;
|
||||||
//; $tls::sig = -9424;
|
//; $tls::sig = -9436;
|
||||||
//; $tls::psig = 3276;
|
//; $tls::psig = 3264;
|
||||||
//; $tls::incyg = -9420;
|
//; $tls::incyg = -9432;
|
||||||
//; $tls::pincyg = 3280;
|
//; $tls::pincyg = 3268;
|
||||||
//; $tls::spinning = -9416;
|
//; $tls::spinning = -9428;
|
||||||
//; $tls::pspinning = 3284;
|
//; $tls::pspinning = 3272;
|
||||||
//; $tls::stacklock = -9412;
|
//; $tls::stacklock = -9424;
|
||||||
//; $tls::pstacklock = 3288;
|
//; $tls::pstacklock = 3276;
|
||||||
//; $tls::stackptr = -9408;
|
//; $tls::stackptr = -9420;
|
||||||
//; $tls::pstackptr = 3292;
|
//; $tls::pstackptr = 3280;
|
||||||
//; $tls::stack = -9404;
|
//; $tls::stack = -9416;
|
||||||
//; $tls::pstack = 3296;
|
//; $tls::pstack = 3284;
|
||||||
//; $tls::initialized = -8380;
|
//; $tls::initialized = -8392;
|
||||||
//; $tls::pinitialized = 4320;
|
//; $tls::pinitialized = 4308;
|
||||||
//; __DATA__
|
//; __DATA__
|
||||||
|
|
||||||
#define tls_func (-12700)
|
#define tls_func (-12700)
|
||||||
|
@ -103,19 +103,19 @@
|
||||||
#define tls_p_ctinfo (3228)
|
#define tls_p_ctinfo (3228)
|
||||||
#define tls_andreas (-9468)
|
#define tls_andreas (-9468)
|
||||||
#define tls_pandreas (3232)
|
#define tls_pandreas (3232)
|
||||||
#define tls_wq (-9452)
|
#define tls_wq (-9464)
|
||||||
#define tls_pwq (3248)
|
#define tls_pwq (3236)
|
||||||
#define tls_sig (-9424)
|
#define tls_sig (-9436)
|
||||||
#define tls_psig (3276)
|
#define tls_psig (3264)
|
||||||
#define tls_incyg (-9420)
|
#define tls_incyg (-9432)
|
||||||
#define tls_pincyg (3280)
|
#define tls_pincyg (3268)
|
||||||
#define tls_spinning (-9416)
|
#define tls_spinning (-9428)
|
||||||
#define tls_pspinning (3284)
|
#define tls_pspinning (3272)
|
||||||
#define tls_stacklock (-9412)
|
#define tls_stacklock (-9424)
|
||||||
#define tls_pstacklock (3288)
|
#define tls_pstacklock (3276)
|
||||||
#define tls_stackptr (-9408)
|
#define tls_stackptr (-9420)
|
||||||
#define tls_pstackptr (3292)
|
#define tls_pstackptr (3280)
|
||||||
#define tls_stack (-9404)
|
#define tls_stack (-9416)
|
||||||
#define tls_pstack (3296)
|
#define tls_pstack (3284)
|
||||||
#define tls_initialized (-8380)
|
#define tls_initialized (-8392)
|
||||||
#define tls_pinitialized (4320)
|
#define tls_pinitialized (4308)
|
||||||
|
|
Loading…
Reference in New Issue