From 6946073e784471e1fc51fffd705b0cbc4d58e730 Mon Sep 17 00:00:00 2001 From: Christopher Faylor <me@cgf.cx> Date: Sun, 8 Feb 2004 19:59:27 +0000 Subject: [PATCH] * localtime.cc (localtime_r): Call tzset. * Makefile.in: Make version.h/cygwin.din version check a warning since it is not foolproof. * cygheap.h (CYGHEAPSIZE): Bump size down. * cygtls.h (_threadinfo::stacklock): New element. (_threadinfo::pop): Make regparm. (_threadinfo::lock): New function. (_threadinfo::unlock): New function. * cygtls.cc (_threadinfo::push): Wait for a lock on the stack before performing the operation. (_threadinfo::pop): Move to another file. * cygwin.din: More SIGFE changes. * exceptions.cc (try_to_debug): Always display messages on console. (handle_exceptions): Unwind stack only when actually about to call sig_send. (setup_handler): Lock stack prior to performing any operations. * gendef (_sigfe): Ditto. (_sigbe): Ditto. (_threadinfo::pop): Ditto. Move here. * gen_tlsoffsets: Generate positive offsets. * tlsoffsets.h: Regenerate. --- winsup/cygwin/ChangeLog | 27 ++++++++ winsup/cygwin/Makefile.in | 3 +- winsup/cygwin/cygheap.h | 2 +- winsup/cygwin/cygtls.cc | 18 ++--- winsup/cygwin/cygtls.h | 5 +- winsup/cygwin/cygwin.din | 25 ++++--- winsup/cygwin/exceptions.cc | 24 ++++--- winsup/cygwin/gendef | 78 +++++++++++++++------ winsup/cygwin/gentls_offsets | 3 + winsup/cygwin/localtime.cc | 1 + winsup/cygwin/tlsoffsets.h | 128 ++++++++++++++++++++++++----------- 11 files changed, 214 insertions(+), 100 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index befb8dd06..e3bd6e296 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,30 @@ +2004-02-08 Christopher Faylor <cgf@redhat.com> + + * localtime.cc (localtime_r): Call tzset. + + * Makefile.in: Make version.h/cygwin.din version check a warning since + it is not foolproof. + + * cygheap.h (CYGHEAPSIZE): Bump size down. + + * cygtls.h (_threadinfo::stacklock): New element. + (_threadinfo::pop): Make regparm. + (_threadinfo::lock): New function. + (_threadinfo::unlock): New function. + * cygtls.cc (_threadinfo::push): Wait for a lock on the stack before + performing the operation. + (_threadinfo::pop): Move to another file. + * cygwin.din: More SIGFE changes. + * exceptions.cc (try_to_debug): Always display messages on console. + (handle_exceptions): Unwind stack only when actually about to call + sig_send. + (setup_handler): Lock stack prior to performing any operations. + * gendef (_sigfe): Ditto. + (_sigbe): Ditto. + (_threadinfo::pop): Ditto. Move here. + * gen_tlsoffsets: Generate positive offsets. + * tlsoffsets.h: Regenerate. + 2004-02-06 Corinna Vinschen <corinna@vinschen.de> * cygserver.h (CYGWIN_SERVER_VERSION_API): Bump. diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index a208ebc27..54ae6e991 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -384,8 +384,7 @@ $(LIBGMON_A): $(GMON_OFILES) $(GMON_START) $(AR) rcv $(LIBGMON_A) $(GMON_OFILES) $(API_VER): $(srcdir)/cygwin.din - @echo Error: Version info is older than DLL API!;\ - false + @echo Error: Version info is older than DLL API! version.cc winver.o: winver_stamp @ : diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index fd649af06..a5134cfde 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -272,7 +272,7 @@ struct init_cygheap void close_ctty (); }; -#define CYGHEAPSIZE (sizeof (init_cygheap) + (20000 * sizeof (fhandler_union)) + (64 * 1024 * 1024)) +#define CYGHEAPSIZE (sizeof (init_cygheap) + (20000 * sizeof (fhandler_union)) + (32 * 1024 * 1024)) extern init_cygheap *cygheap; extern void *cygheap_max; diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index a74412637..becde2d73 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -155,24 +155,14 @@ _threadinfo::remove (DWORD wait) void _threadinfo::push (__stack_t addr, bool exception) { + if (exception) + lock (true); *stackptr++ = (__stack_t) addr; + if (exception) + unlock (); set_state (exception); } -__stack_t -_threadinfo::pop () -{ -#ifdef DEBUGGING - assert (stackptr > stack); -#endif - __stack_t res = *--stackptr; -#ifdef DEBUGGING - *stackptr = 0; - debug_printf ("popped %p, stack %p, stackptr %p", res, stack, stackptr); -#endif - return res; -} - #define BAD_IX ((size_t) -1) static size_t NO_COPY threadlist_ix = BAD_IX; diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index e2f5f0b3a..c1525a45d 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -111,6 +111,7 @@ struct _threadinfo struct _threadinfo *prev, *next; __stack_t *stackptr; int sig; + unsigned stacklock; __stack_t stack[TLS_STACK_SIZE]; unsigned padding[0]; @@ -123,7 +124,7 @@ struct _threadinfo static struct _threadinfo *find_tls (int sig); void remove (DWORD); void push (__stack_t, bool = false) __attribute__ ((regparm (3))); - __stack_t pop (); + __stack_t pop () __attribute__ ((regparm (1))); bool isinitialized () {return initialized == CYGTLS_INITIALIZED || initialized == CYGTLS_EXCEPTION;} void set_state (bool); void reset_exception (); @@ -136,6 +137,8 @@ struct _threadinfo void set_siginfo (struct sigpacket *) __attribute__ ((regparm (3))); void set_threadkill () {threadkill = true;} void reset_threadkill () {threadkill = false;} + int lock (int wait) __attribute__ ((regparm (2))); + void unlock () __attribute__ ((regparm (1))); /*gentls_offsets*/ }; #pragma pack(pop) diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index 9f8553665..1a9e47a64 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -479,19 +479,19 @@ fdimf NOSIGFE fdopen SIGFE _fdopen = fdopen SIGFE _fdopen64 = fdopen64 SIGFE -feof NOSIGFE -_feof = feof NOSIGFE +feof SIGFE +_feof = feof SIGFE ferror NOSIGFE _ferror = ferror NOSIGFE -fflush NOSIGFE -_fflush = fflush NOSIGFE +fflush SIGFE +_fflush = fflush SIGFE ffs NOSIGFE _ffs = ffs NOSIGFE fgetc SIGFE _fgetc = fgetc SIGFE -fgetpos NOSIGFE -_fgetpos = fgetpos NOSIGFE -_fgetpos64 = fgetpos64 NOSIGFE +fgetpos SIGFE +_fgetpos = fgetpos SIGFE +_fgetpos64 = fgetpos64 SIGFE fgets SIGFE _fgets = fgets SIGFE fileno NOSIGFE @@ -503,7 +503,6 @@ _finitef = finitef NOSIGFE fiprintf SIGFE _fiprintf = fiprintf SIGFE flock SIGFE -flock SIGFE floor NOSIGFE _floor = floor NOSIGFE floorf NOSIGFE @@ -559,11 +558,11 @@ fstatfs SIGFE _fstatfs = fstatfs SIGFE fsync SIGFE _fsync = fsync SIGFE -ftell NOSIGFE -_ftell = ftell NOSIGFE -ftello NOSIGFE -_ftello = ftello NOSIGFE -_ftello64 = ftello64 NOSIGFE +ftell SIGFE +_ftell = ftell SIGFE +ftello SIGFE +_ftello = ftello SIGFE +_ftello64 = ftello64 SIGFE ftime SIGFE _ftime = ftime SIGFE ftok SIGFE diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 4983a2ede..e90d093a2 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -361,8 +361,8 @@ try_to_debug (bool waitloop) } } - small_printf ("*** starting debugger for pid %u\n", - cygwin_pid (GetCurrentProcessId ())); + console_printf ("*** starting debugger for pid %u\n", + cygwin_pid (GetCurrentProcessId ())); BOOL dbg; dbg = CreateProcess (NULL, debugger_command, @@ -380,17 +380,18 @@ try_to_debug (bool waitloop) else { if (!waitloop) - return 1; + return dbg; SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_IDLE); while (!being_debugged ()) Sleep (0); Sleep (2000); - small_printf ("*** continuing pid %u from debugger call\n", - cygwin_pid (GetCurrentProcessId ())); } + console_printf ("*** continuing pid %u from debugger call (%d)\n", + cygwin_pid (GetCurrentProcessId ()), dbg); + SetThreadPriority (GetCurrentThread (), prio); - return 0; + return dbg; } /* Main exception handler. */ @@ -416,10 +417,6 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *) EXCEPTION_RECORD e = *e0; CONTEXT in = *in0; - extern DWORD ret_here[]; - RtlUnwind (frame, ret_here, e0, 0); - __asm__ volatile (".equ _ret_here,."); - siginfo_t si; /* Coerce win32 value to posix value. */ switch (e.ExceptionCode) @@ -557,6 +554,10 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *) signal_exit (0x80 | si.si_signo); // Flag signal + core dump } + extern DWORD ret_here[]; + RtlUnwind (frame, ret_here, e0, 0); + __asm__ volatile (".equ _ret_here,."); + si.si_addr = ebp; si.si_code = SI_KERNEL; si.si_errno = si.si_pid = si.si_uid = 0; @@ -766,12 +767,15 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _threadinfo *tls) __stack_t *retaddr_on_stack = tls->stackptr - 1; if (retaddr_on_stack >= tls->stack) { + if (!tls->lock (false)) + continue; __stack_t retaddr = InterlockedExchange ((LONG *) retaddr_on_stack, 0); if (!retaddr) continue; tls->reset_exception (); tls->interrupt_setup (sig, handler, siga, retaddr); sigproc_printf ("interrupted known cygwin routine"); + tls->unlock (); interrupted = true; break; } diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index d317eeacd..2457314b2 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -88,40 +88,79 @@ EOF if (!$main::first++) { $res = <<EOF . longjmp () . $res; .text - .global __sigbe - .global _sigreturn - .global _sigdelayed .stabs "_sigfe:F(0,1)",36,0,0,__sigbe __sigfe: pushl %edx - movl %fs:4,%eax - movl \$4,%edx - xadd %edx,$tls::stackptr(%eax) - leal __sigbe,%eax - xchg %eax,8(%esp) - movl %eax,(%edx) + movl %fs:4,%edx +1: movl \$1,%eax + lock cmpxchg %eax,$tls::stacklock(%edx) + jne 2f + xorl %eax,%eax + call _low_priority_sleep + jmp 1b +2: movl \$4,%eax + xadd %eax,$tls::stackptr(%edx) + decl $tls::stacklock(%edx) + leal __sigbe,%edx + xchg %edx,8(%esp) + movl %edx,(%eax) popl %edx ret + .global __sigbe .stabs "_sigbe:F(0,1)",36,0,0,__sigbe __sigbe: - pushl %eax pushl %edx - movl \$-4,%edx -1: movl %fs:4,%eax - xadd %edx,$tls::stackptr(%eax) + pushl %eax + movl %fs:4,%edx +1: movl \$1,%eax + lock cmpxchg %eax,$tls::stacklock(%edx) + jne 2f xorl %eax,%eax - lock xchg %eax,-4(%edx) - testl %eax,%eax - jnz 2f call _low_priority_sleep - xorl %edx,%edx jmp 1b -2: xchg %eax,4(%esp) - popl %edx +2: movl \$-4,%eax + xadd %eax,$tls::stackptr(%edx) + xchg %edx,-4(%eax) + xchg %edx,4(%esp) + popl %eax ret + .global __ZN11_threadinfo3popEv +__ZN11_threadinfo3popEv: +1: pushl %ebx + movl %eax,%edx + movl \$-4,%ebx + xadd %ebx,$tls::pstackptr(%edx) + xorl %eax,%eax + xchg %eax,-4(%ebx) + decl $tls::pstacklock(%edx) + popl %ebx + ret + + .global __ZN11_threadinfo4lockEi +__ZN11_threadinfo4lockEi: + pushl %ebx + movl %eax,%ebx +1: movl \$1,%eax + lock cmpxchg %eax,$tls::pstacklock(%ebx) + jne 2f + cmpl %edx,%edx + jz 2f + xorl %eax,%eax + call _low_priority_sleep + jmp 1b +2: xorl \$1,%eax + popl %ebx + ret + + .global __ZN11_threadinfo6unlockEv +__ZN11_threadinfo6unlockEv: + decl $tls::pstacklock(%eax) + ret + + .global _sigreturn .stabs "sigreturn:F(0,1)",36,0,0,_sigreturn _sigreturn: addl \$4,%esp # Remove argument @@ -147,6 +186,7 @@ _sigreturn: popl %ebp jmp __sigbe + .global _sigdelayed .stabs "sigdelayed:F(0,1)",36,0,0,_sigdelayed _sigdelayed: pushl %ebp diff --git a/winsup/cygwin/gentls_offsets b/winsup/cygwin/gentls_offsets index 375b66840..c69488a36 100755 --- a/winsup/cygwin/gentls_offsets +++ b/winsup/cygwin/gentls_offsets @@ -50,14 +50,17 @@ main(int argc, char **argv) $struct foo[1]; # define foo_end ((char *) (foo + 1)) # define offset(f) (((char *) &(foo->f)) - foo_end) +# define poffset(f) (((char *) &(foo->f)) - ((char *) foo)) EOF print TMP 'puts ("//;# autogenerated: Do not edit.\n");', "\n\n"; for my $f (@fields) { print TMP ' printf ("//; $tls::', $f, ' = %d;\n", ', "offset($f));\n"; + print TMP ' printf ("//; $tls::p', $f, ' = %d;\n", ', "poffset($f));\n"; } print TMP ' puts ("//; __DATA__\n");', "\n"; for my $f (@fields) { print TMP ' printf ("#define tls_', $f, ' (%d)\n", ', "offset($f));\n"; + print TMP ' printf ("#define tls_p', $f, ' (%d)\n", ', "poffset($f));\n"; } print TMP <<EOF; diff --git a/winsup/cygwin/localtime.cc b/winsup/cygwin/localtime.cc index 3a64d689c..548f9d2e1 100644 --- a/winsup/cygwin/localtime.cc +++ b/winsup/cygwin/localtime.cc @@ -1565,6 +1565,7 @@ localtime(const time_t *timep) extern "C" struct tm * localtime_r(const time_t *timep, struct tm *tm) { + tzset(); localsub(timep, 0L, tm); return tm; } diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h index 51034302b..e1da0395a 100644 --- a/winsup/cygwin/tlsoffsets.h +++ b/winsup/cygwin/tlsoffsets.h @@ -1,48 +1,96 @@ //;# autogenerated: Do not edit. -//; $tls::func = -3736; -//; $tls::saved_errno = -3732; -//; $tls::sa_flags = -3728; -//; $tls::oldmask = -3724; -//; $tls::newmask = -3720; -//; $tls::event = -3716; -//; $tls::errno_addr = -3712; -//; $tls::initialized = -3708; -//; $tls::sigmask = -3704; -//; $tls::sigwait_mask = -3700; -//; $tls::sigwait_info = -3696; -//; $tls::threadkill = -3692; -//; $tls::infodata = -3688; -//; $tls::tid = -3540; -//; $tls::local_clib = -3536; -//; $tls::locals = -2608; -//; $tls::prev = -1040; -//; $tls::next = -1036; -//; $tls::stackptr = -1032; -//; $tls::sig = -1028; +//; $tls::func = -3740; +//; $tls::pfunc = 0; +//; $tls::saved_errno = -3736; +//; $tls::psaved_errno = 4; +//; $tls::sa_flags = -3732; +//; $tls::psa_flags = 8; +//; $tls::oldmask = -3728; +//; $tls::poldmask = 12; +//; $tls::newmask = -3724; +//; $tls::pnewmask = 16; +//; $tls::event = -3720; +//; $tls::pevent = 20; +//; $tls::errno_addr = -3716; +//; $tls::perrno_addr = 24; +//; $tls::initialized = -3712; +//; $tls::pinitialized = 28; +//; $tls::sigmask = -3708; +//; $tls::psigmask = 32; +//; $tls::sigwait_mask = -3704; +//; $tls::psigwait_mask = 36; +//; $tls::sigwait_info = -3700; +//; $tls::psigwait_info = 40; +//; $tls::threadkill = -3696; +//; $tls::pthreadkill = 44; +//; $tls::infodata = -3692; +//; $tls::pinfodata = 48; +//; $tls::tid = -3544; +//; $tls::ptid = 196; +//; $tls::local_clib = -3540; +//; $tls::plocal_clib = 200; +//; $tls::locals = -2612; +//; $tls::plocals = 1128; +//; $tls::prev = -1044; +//; $tls::pprev = 2696; +//; $tls::next = -1040; +//; $tls::pnext = 2700; +//; $tls::stackptr = -1036; +//; $tls::pstackptr = 2704; +//; $tls::sig = -1032; +//; $tls::psig = 2708; +//; $tls::stacklock = -1028; +//; $tls::pstacklock = 2712; //; $tls::stack = -1024; +//; $tls::pstack = 2716; //; $tls::padding = 0; +//; $tls::ppadding = 3740; //; __DATA__ -#define tls_func (-3736) -#define tls_saved_errno (-3732) -#define tls_sa_flags (-3728) -#define tls_oldmask (-3724) -#define tls_newmask (-3720) -#define tls_event (-3716) -#define tls_errno_addr (-3712) -#define tls_initialized (-3708) -#define tls_sigmask (-3704) -#define tls_sigwait_mask (-3700) -#define tls_sigwait_info (-3696) -#define tls_threadkill (-3692) -#define tls_infodata (-3688) -#define tls_tid (-3540) -#define tls_local_clib (-3536) -#define tls_locals (-2608) -#define tls_prev (-1040) -#define tls_next (-1036) -#define tls_stackptr (-1032) -#define tls_sig (-1028) +#define tls_func (-3740) +#define tls_pfunc (0) +#define tls_saved_errno (-3736) +#define tls_psaved_errno (4) +#define tls_sa_flags (-3732) +#define tls_psa_flags (8) +#define tls_oldmask (-3728) +#define tls_poldmask (12) +#define tls_newmask (-3724) +#define tls_pnewmask (16) +#define tls_event (-3720) +#define tls_pevent (20) +#define tls_errno_addr (-3716) +#define tls_perrno_addr (24) +#define tls_initialized (-3712) +#define tls_pinitialized (28) +#define tls_sigmask (-3708) +#define tls_psigmask (32) +#define tls_sigwait_mask (-3704) +#define tls_psigwait_mask (36) +#define tls_sigwait_info (-3700) +#define tls_psigwait_info (40) +#define tls_threadkill (-3696) +#define tls_pthreadkill (44) +#define tls_infodata (-3692) +#define tls_pinfodata (48) +#define tls_tid (-3544) +#define tls_ptid (196) +#define tls_local_clib (-3540) +#define tls_plocal_clib (200) +#define tls_locals (-2612) +#define tls_plocals (1128) +#define tls_prev (-1044) +#define tls_pprev (2696) +#define tls_next (-1040) +#define tls_pnext (2700) +#define tls_stackptr (-1036) +#define tls_pstackptr (2704) +#define tls_sig (-1032) +#define tls_psig (2708) +#define tls_stacklock (-1028) +#define tls_pstacklock (2712) #define tls_stack (-1024) +#define tls_pstack (2716) #define tls_padding (0) +#define tls_ppadding (3740)