diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 9126ddf2b..fe83089da 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,30 @@ +2006-02-06 Christopher Faylor + + Always zero all elements of siginfo_t throughout. + * cygtls.h (_cygtls::thread_context): Declare new field. + (_cygtls::thread_id): Ditto. + (_cygtls::signal_exit): Move into this class. + (_cygtls::copy_context): Declare new function. + (_cygtls::signal_debugger): Ditto. + * cygtls.cc (_cygtls::init_thread): Fill out thread id field. + * exceptions.cc (exception): Change message when exception info is + unknown. Copy context to thread local storage. + (_cygtls::handle_exceptions): Avoid double test for fault_guarded. + Reflect move of signal_exit to _cygtls class. + (sigpacket::process): Copy context to thread local storage. + (_cygtls::signal_exit): Move to _cygtls class. Call signal_debugger to + notify debugger of exiting signal (WIP). Call stackdump here (WIP). + (_cygtls::copy_context): Define new function. + (_cygtls::signal_debugger): Ditto. + * tlsoffsets.h: Regenerate. + * include/cygwin.h (_fpstate): New internal structure. + (ucontext): Declare new structure (WIP). + (__COPY_CONTEXT_SIZE): New define. + + * exceptions.cc (_cygtls::interrupt_setup): Clear "threadkill" field + when there is no sigwaiting thread. + (setup_handler): Move event handling into interrupt_setup. + 2006-02-06 Corinna Vinschen * fhandler_socket.cc (fhandler_socket::connect): Fix formatting. diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index 89466a50e..387316c8d 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -100,6 +100,7 @@ _cygtls::init_thread (void *x, DWORD (*func) (void *, void *)) init_exception_handler (handle_exceptions); } + thread_id = GetCurrentThreadId (); initialized = CYGTLS_INITIALIZED; locals.exitsock = INVALID_SOCKET; errno_addr = &(local_clib._errno); diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 6feee64d0..609eb9697 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -149,6 +149,8 @@ struct _cygtls sigset_t sigmask; sigset_t sigwait_mask; siginfo_t *sigwait_info; + struct ucontext thread_context; + DWORD thread_id; unsigned threadkill; siginfo_t infodata; struct pthread *tid; @@ -193,6 +195,9 @@ struct _cygtls static int handle_threadlist_exception (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *c, void *); void init_exception_handler (int (*) (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void*)); void init_threadlist_exceptions (); + void signal_exit (int) __attribute__ ((noreturn, regparm(2))); + void copy_context (CONTEXT *) __attribute__ ((regparm(2))); + void signal_debugger (int) __attribute__ ((regparm(2))); #ifdef _THREAD_H operator HANDLE () const {return tid->win32_obj_id;} diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 3c8a7c8e4..8122939b6 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -1075,10 +1075,9 @@ do_exit (int status) /* Kill orphaned children on group leader exit */ if (myself->has_pgid_children && myself->pid == myself->pgid) { - siginfo_t si; + siginfo_t si = {0}; si.si_signo = -SIGHUP; si.si_code = SI_KERNEL; - si.si_pid = si.si_uid = si.si_errno = 0; sigproc_printf ("%d == pgrp %d, send SIG{HUP,CONT} to stopped children", myself->pid, myself->pgid); kill_pgrp (myself->pgid, si); diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index cc34e8d74..4162ebd6b 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -44,7 +44,6 @@ extern NO_COPY DWORD dwExeced; int NO_COPY sigExeced; static BOOL WINAPI ctrl_c_handler (DWORD); -static void signal_exit (int) __attribute__ ((noreturn)); char windows_system_directory[1024]; static size_t windows_system_directory_length; @@ -184,7 +183,7 @@ exception (EXCEPTION_RECORD *e, CONTEXT *in) if (exception_name) small_printf ("Exception: %s at eip=%08x\r\n", exception_name, in->Eip); else - small_printf ("Exception %d at eip=%08x\r\n", e->ExceptionCode, in->Eip); + small_printf ("Signal %d at eip=%08x\r\n", e->ExceptionCode, in->Eip); small_printf ("eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\r\n", in->Eax, in->Ebx, in->Ecx, in->Edx, in->Esi, in->Edi); small_printf ("ebp=%08x esp=%08x program=%s, pid %u, thread %s\r\n", @@ -454,7 +453,7 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT if (exit_already || e->ExceptionFlags) return 1; - siginfo_t si; + siginfo_t si = {0}; si.si_code = SI_KERNEL; /* Coerce win32 value to posix value. */ switch (e->ExceptionCode) @@ -579,12 +578,15 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT break; } - if (!me.fault_guarded () - && (!cygwin_finished_initializing - || &me == _sig_tls - || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL - || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN - || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR)) + if (me.fault_guarded ()) + me.return_from_fault (); + + me.copy_context (in); + if (!cygwin_finished_initializing + || &me == _sig_tls + || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL + || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN + || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR) { /* Print the exception to the console */ if (!myself->cygstarted) @@ -613,7 +615,7 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT } if (e->ExceptionCode == STATUS_ACCESS_VIOLATION) - { + { int error_code = 0; if (si.si_code == SEGV_ACCERR) /* Address present */ error_code |= 1; @@ -628,12 +630,9 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT ? 0 : 4) | (e->ExceptionInformation[0] << 1)); } - signal_exit (0x80 | si.si_signo); // Flag signal + core dump + me.signal_exit (0x80 | si.si_signo); // Flag signal + core dump } - if (me.fault_guarded ()) - me.return_from_fault (); - si.si_addr = (void *) in->Eip; si.si_errno = si.si_pid = si.si_uid = 0; me.incyg++; @@ -755,6 +754,15 @@ _cygtls::interrupt_setup (int sig, void *handler, struct sigaction& siga) this->sig = sig; // Should always be last thing set to avoid a race + if (!event) + threadkill = false; + else + { + HANDLE h = event; + event = NULL; + SetEvent (h); + } + /* Clear any waiting threads prior to dispatching to handler function */ int res = SetEvent (signal_arrived); // For an EINTR case proc_subproc (PROC_CLEARWAIT, 1); @@ -841,12 +849,6 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls) } out: - if (interrupted && tls->event) - { - HANDLE h = tls->event; - tls->event = NULL; - SetEvent (h); - } sigproc_printf ("signal %d %sdelivered", sig, interrupted ? "" : "not "); return interrupted; } @@ -1209,19 +1211,18 @@ exit_sig: CONTEXT c; c.ContextFlags = CONTEXT_FULL; GetThreadContext (hMainThread, &c); - if (!try_to_debug ()) - stackdump (c.Ebp, 1, 1); + tls->copy_context (&c); si.si_signo |= 0x80; } sigproc_printf ("signal %d, about to call do_exit", si.si_signo); - signal_exit (si.si_signo); /* never returns */ + tls->signal_exit (si.si_signo); /* never returns */ } /* Cover function to `do_exit' to handle exiting even in presence of more exceptions. We used to call exit, but a SIGSEGV shouldn't cause atexit routines to run. */ -static void -signal_exit (int rc) +void +_cygtls::signal_exit (int rc) { if (hExeced) { @@ -1229,6 +1230,10 @@ signal_exit (int rc) TerminateProcess (hExeced, sigExeced = rc); } + signal_debugger (rc & 0x7f); + if ((rc & 0x80) && !try_to_debug ()) + stackdump (thread_context.ebp, 1, 1); + lock_process until_exit (true); if (hExeced || exit_state) myself.exit (rc); @@ -1331,3 +1336,20 @@ reset_signal_arrived () if (_my_tls.stackptr > _my_tls.stack) debug_printf ("stackptr[-1] %p", _my_tls.stackptr[-1]); } + +void +_cygtls::copy_context (CONTEXT *c) +{ + memcpy (&thread_context, c, (&thread_context._internal - (unsigned char *) &thread_context)); +} + +void +_cygtls::signal_debugger (int sig) +{ + if (being_debugged ()) + { + char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING " ffffffff ffffffff")]; + __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %d %p %p", sig, thread_id, &thread_context); + OutputDebugString (sigmsg); + } +} diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc index d607ea6b4..9b1098fca 100644 --- a/winsup/cygwin/fhandler_termios.cc +++ b/winsup/cygwin/fhandler_termios.cc @@ -110,10 +110,9 @@ tty_min::kill_pgrp (int sig) { int killself = 0; winpids pids ((DWORD) PID_MAP_RW); - siginfo_t si; + siginfo_t si = {0}; si.si_signo = sig; si.si_code = SI_KERNEL; - si.si_pid = si.si_uid = si.si_errno = 0; for (unsigned i = 0; i < pids.npids; i++) { _pinfo *p = pids[i]; @@ -172,10 +171,9 @@ fhandler_termios::bg_check (int sig) by another signal. */ if (WaitForSingleObject (signal_arrived, 0) != WAIT_OBJECT_0) { - siginfo_t si; + siginfo_t si = {0}; si.si_signo = sig; si.si_code = SI_KERNEL; - si.si_pid = si.si_uid = si.si_errno = 0; kill_pgrp (myself->pgid, si); } return bg_signalled; diff --git a/winsup/cygwin/include/cygwin/signal.h b/winsup/cygwin/include/cygwin/signal.h index 7dff34e16..fd6110969 100644 --- a/winsup/cygwin/include/cygwin/signal.h +++ b/winsup/cygwin/include/cygwin/signal.h @@ -1,6 +1,6 @@ /* signal.h - Copyright 2004, 2006 Red Hat, Inc. + Copyright 2004, 2005, 2006 Red Hat, Inc. This file is part of Cygwin. @@ -14,17 +14,50 @@ #ifdef __cplusplus extern "C" { #endif +struct _fpstate +{ + unsigned long cw; + unsigned long sw; + unsigned long tag; + unsigned long ipoff; + unsigned long cssel; + unsigned long dataoff; + unsigned long datasel; + unsigned char _st[80]; + unsigned long nxst; +}; -#if 0 struct ucontext { - unsigned long uc_flags; - void *uc_link; - stack_t uc_stack; - struct sigcontext uc_mcontext; - sigset_t uc_sigmask; + unsigned long cr2; + unsigned long dr0; + unsigned long dr1; + unsigned long dr2; + unsigned long dr3; + unsigned long dr6; + unsigned long dr7; + struct _fpstate fpstate; + unsigned long gs; + unsigned long fs; + unsigned long es; + unsigned long ds; + unsigned long edi; + unsigned long esi; + unsigned long ebx; + unsigned long edx; + unsigned long ecx; + unsigned long eax; + unsigned long ebp; + unsigned long eip; + unsigned long cs; + unsigned long eflags; + unsigned long esp; + unsigned long ss; + unsigned char _internal; + unsigned long oldmask; }; -#endif + +#define __COPY_CONTEXT_SIZE ((unsigned) &((struct ucontext *) 0)->_internal) typedef union sigval { diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 7267ed0fb..c71299ff0 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -836,17 +836,13 @@ proc_waiter (void *arg) pinfo vchild = *(pinfo *) arg; ((pinfo *) arg)->waiter_ready = true; - siginfo_t si; + siginfo_t si = {0}; si.si_signo = SIGCHLD; si.si_code = CLD_EXITED; si.si_pid = vchild->pid; - si.si_errno = 0; #if 0 // FIXME: This is tricky to get right si.si_utime = pchildren[rc]->rusage_self.ru_utime; si.si_stime = pchildren[rc].rusage_self.ru_stime; -#else - si.si_utime = 0; - si.si_stime = 0; #endif pid_t pid = vchild->pid; diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 09e8eee0e..1055b5fe9 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -209,10 +209,9 @@ _pinfo::kill (siginfo_t& si) } else if (sendSIGCONT) { - siginfo_t si2; + siginfo_t si2 = {0}; si2.si_signo = SIGCONT; si2.si_code = SI_KERNEL; - si2.si_pid = si2.si_uid = si2.si_errno = 0; sig_send (this, si2); } @@ -251,20 +250,18 @@ kill0 (pid_t pid, siginfo_t& si) int killsys (pid_t pid, int sig) { - siginfo_t si; + siginfo_t si = {0}; si.si_signo = sig; si.si_code = SI_KERNEL; - si.si_pid = si.si_uid = si.si_errno = 0; return kill0 (pid, si); } int kill (pid_t pid, int sig) { - siginfo_t si; + siginfo_t si = {0}; si.si_signo = sig; si.si_code = SI_USER; - si.si_pid = si.si_uid = si.si_errno = 0; return kill0 (pid, si); } @@ -538,7 +535,7 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info) extern "C" int sigqueue (pid_t pid, int sig, const union sigval value) { - siginfo_t si; + siginfo_t si = {0}; pinfo dest (pid); if (!dest) { @@ -547,7 +544,6 @@ sigqueue (pid_t pid, int sig, const union sigval value) } si.si_signo = sig; si.si_code = SI_QUEUE; - si.si_pid = si.si_uid = si.si_errno = 0; si.si_value = value; return sig_send (dest, si); } diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 886cbdabe..ab8699128 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -514,7 +514,7 @@ sig_send (_pinfo *p, int sig) { if (sig == __SIGNOHOLD) SetEvent (sigCONT); - siginfo_t si; + siginfo_t si = {0}; si.si_signo = sig; si.si_code = SI_KERNEL; si.si_pid = si.si_uid = si.si_errno = 0; diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 8ad16c3c8..d7b2a1fa2 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -2870,12 +2870,11 @@ pthread_kill (pthread_t thread, int sig) if (!pthread::is_good_object (&thread)) return EINVAL; - siginfo_t si; + siginfo_t si = {0}; si.si_signo = sig; si.si_code = SI_USER; si.si_pid = myself->pid; si.si_uid = myself->uid; - si.si_errno = 0; thread->cygtls->set_threadkill (); int rval = sig ? sig_send (NULL, si, thread->cygtls) : 0; diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index 30164207d..7dea7ea69 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -164,8 +164,7 @@ timer_thread (VOID *x) { case SIGEV_SIGNAL: { - siginfo_t si; - memset (&si, 0, sizeof (si)); + siginfo_t si = {0}; si.si_signo = tt->evp.sigev_signo; si.si_sigval.sival_ptr = tt->evp.sigev_value.sival_ptr; si.si_code = SI_TIMER; diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h index eebcfcaf0..8e9aec833 100644 --- a/winsup/cygwin/tlsoffsets.h +++ b/winsup/cygwin/tlsoffsets.h @@ -1,125 +1,133 @@ //;# autogenerated: Do not edit. -//; $tls::sizeof__cygtls = 3996; -//; $tls::func = -3996; +//; $tls::sizeof__cygtls = 4212; +//; $tls::func = -4212; //; $tls::pfunc = 0; -//; $tls::saved_errno = -3992; +//; $tls::saved_errno = -4208; //; $tls::psaved_errno = 4; -//; $tls::sa_flags = -3988; +//; $tls::sa_flags = -4204; //; $tls::psa_flags = 8; -//; $tls::oldmask = -3984; +//; $tls::oldmask = -4200; //; $tls::poldmask = 12; -//; $tls::deltamask = -3980; +//; $tls::deltamask = -4196; //; $tls::pdeltamask = 16; -//; $tls::event = -3976; +//; $tls::event = -4192; //; $tls::pevent = 20; -//; $tls::errno_addr = -3972; +//; $tls::errno_addr = -4188; //; $tls::perrno_addr = 24; -//; $tls::initialized = -3968; +//; $tls::initialized = -4184; //; $tls::pinitialized = 28; -//; $tls::sigmask = -3964; +//; $tls::sigmask = -4180; //; $tls::psigmask = 32; -//; $tls::sigwait_mask = -3960; +//; $tls::sigwait_mask = -4176; //; $tls::psigwait_mask = 36; -//; $tls::sigwait_info = -3956; +//; $tls::sigwait_info = -4172; //; $tls::psigwait_info = 40; +//; $tls::thread_context = -4168; +//; $tls::pthread_context = 44; +//; $tls::thread_id = -3956; +//; $tls::pthread_id = 256; //; $tls::threadkill = -3952; -//; $tls::pthreadkill = 44; +//; $tls::pthreadkill = 260; //; $tls::infodata = -3948; -//; $tls::pinfodata = 48; +//; $tls::pinfodata = 264; //; $tls::tid = -3800; -//; $tls::ptid = 196; +//; $tls::ptid = 412; //; $tls::local_clib = -3796; -//; $tls::plocal_clib = 200; +//; $tls::plocal_clib = 416; //; $tls::__dontuse = -3796; -//; $tls::p__dontuse = 200; +//; $tls::p__dontuse = 416; //; $tls::locals = -2732; -//; $tls::plocals = 1264; +//; $tls::plocals = 1480; //; $tls::_ctinfo = -1100; -//; $tls::p_ctinfo = 2896; +//; $tls::p_ctinfo = 3112; //; $tls::el = -1096; -//; $tls::pel = 2900; +//; $tls::pel = 3116; //; $tls::andreas = -1088; -//; $tls::pandreas = 2908; +//; $tls::pandreas = 3124; //; $tls::wq = -1080; -//; $tls::pwq = 2916; +//; $tls::pwq = 3132; //; $tls::prev = -1052; -//; $tls::pprev = 2944; +//; $tls::pprev = 3160; //; $tls::next = -1048; -//; $tls::pnext = 2948; +//; $tls::pnext = 3164; //; $tls::sig = -1044; -//; $tls::psig = 2952; +//; $tls::psig = 3168; //; $tls::incyg = -1040; -//; $tls::pincyg = 2956; +//; $tls::pincyg = 3172; //; $tls::spinning = -1036; -//; $tls::pspinning = 2960; +//; $tls::pspinning = 3176; //; $tls::stacklock = -1032; -//; $tls::pstacklock = 2964; +//; $tls::pstacklock = 3180; //; $tls::stackptr = -1028; -//; $tls::pstackptr = 2968; +//; $tls::pstackptr = 3184; //; $tls::stack = -1024; -//; $tls::pstack = 2972; +//; $tls::pstack = 3188; //; $tls::padding = 0; -//; $tls::ppadding = 3996; +//; $tls::ppadding = 4212; //; __DATA__ -#define tls_func (-3996) +#define tls_func (-4212) #define tls_pfunc (0) -#define tls_saved_errno (-3992) +#define tls_saved_errno (-4208) #define tls_psaved_errno (4) -#define tls_sa_flags (-3988) +#define tls_sa_flags (-4204) #define tls_psa_flags (8) -#define tls_oldmask (-3984) +#define tls_oldmask (-4200) #define tls_poldmask (12) -#define tls_deltamask (-3980) +#define tls_deltamask (-4196) #define tls_pdeltamask (16) -#define tls_event (-3976) +#define tls_event (-4192) #define tls_pevent (20) -#define tls_errno_addr (-3972) +#define tls_errno_addr (-4188) #define tls_perrno_addr (24) -#define tls_initialized (-3968) +#define tls_initialized (-4184) #define tls_pinitialized (28) -#define tls_sigmask (-3964) +#define tls_sigmask (-4180) #define tls_psigmask (32) -#define tls_sigwait_mask (-3960) +#define tls_sigwait_mask (-4176) #define tls_psigwait_mask (36) -#define tls_sigwait_info (-3956) +#define tls_sigwait_info (-4172) #define tls_psigwait_info (40) +#define tls_thread_context (-4168) +#define tls_pthread_context (44) +#define tls_thread_id (-3956) +#define tls_pthread_id (256) #define tls_threadkill (-3952) -#define tls_pthreadkill (44) +#define tls_pthreadkill (260) #define tls_infodata (-3948) -#define tls_pinfodata (48) +#define tls_pinfodata (264) #define tls_tid (-3800) -#define tls_ptid (196) +#define tls_ptid (412) #define tls_local_clib (-3796) -#define tls_plocal_clib (200) +#define tls_plocal_clib (416) #define tls___dontuse (-3796) -#define tls_p__dontuse (200) +#define tls_p__dontuse (416) #define tls_locals (-2732) -#define tls_plocals (1264) +#define tls_plocals (1480) #define tls__ctinfo (-1100) -#define tls_p_ctinfo (2896) +#define tls_p_ctinfo (3112) #define tls_el (-1096) -#define tls_pel (2900) +#define tls_pel (3116) #define tls_andreas (-1088) -#define tls_pandreas (2908) +#define tls_pandreas (3124) #define tls_wq (-1080) -#define tls_pwq (2916) +#define tls_pwq (3132) #define tls_prev (-1052) -#define tls_pprev (2944) +#define tls_pprev (3160) #define tls_next (-1048) -#define tls_pnext (2948) +#define tls_pnext (3164) #define tls_sig (-1044) -#define tls_psig (2952) +#define tls_psig (3168) #define tls_incyg (-1040) -#define tls_pincyg (2956) +#define tls_pincyg (3172) #define tls_spinning (-1036) -#define tls_pspinning (2960) +#define tls_pspinning (3176) #define tls_stacklock (-1032) -#define tls_pstacklock (2964) +#define tls_pstacklock (3180) #define tls_stackptr (-1028) -#define tls_pstackptr (2968) +#define tls_pstackptr (3184) #define tls_stack (-1024) -#define tls_pstack (2972) +#define tls_pstack (3188) #define tls_padding (0) -#define tls_ppadding (3996) +#define tls_ppadding (4212)