From c0188ae7cb897a305aea3a54058bb8d444441474 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Mon, 6 Nov 2000 23:12:05 +0000 Subject: [PATCH] * dcrt0.cc (sigthread::init): Reinstitute sigthread lock as a critical section. (dll_crt0_1): Move sigthread lock initialization to earlier in startup. * exceptions.cc (interrupt_on_return): Remove previous kludgy attempt to detect an invalid frame. (call_handler): Eliminate inner for loop. Grab signal critical section lock where appropriate. * sigproc.cc (proc_subproc): Restore uid setting. * sigproc.h (sigthread): Reinstitute sigthread lock as a critical section. (sigframe): Grab the sigthread lock before clearing frame to avoid having the signal thread use an invalid frame. --- winsup/cygwin/ChangeLog | 15 +++++ winsup/cygwin/dcrt0.cc | 9 +-- winsup/cygwin/exceptions.cc | 125 +++++++++++++++--------------------- winsup/cygwin/sigproc.cc | 1 + winsup/cygwin/sigproc.h | 6 +- 5 files changed, 74 insertions(+), 82 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 69cc0a527..d55b6eef7 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,18 @@ +Mon Nov 6 15:11:57 2000 Christopher Faylor + + * dcrt0.cc (sigthread::init): Reinstitute sigthread lock as a critical + section. + (dll_crt0_1): Move sigthread lock initialization to earlier in startup. + * exceptions.cc (interrupt_on_return): Remove previous kludgy attempt + to detect an invalid frame. + (call_handler): Eliminate inner for loop. Grab signal critical section + lock where appropriate. + * sigproc.cc (proc_subproc): Restore uid setting. + * sigproc.h (sigthread): Reinstitute sigthread lock as a critical + section. + (sigframe): Grab the sigthread lock before clearing frame to avoid + having the signal thread use an invalid frame. + Mon Nov 6 11:11:42 2000 Jason Tishler * path.cc (mount_info::read_cygdrive_info_from_registry): Use diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index faa7cfa6e..4362a779e 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -613,9 +613,7 @@ char _declspec(dllexport) **__argv = NULL; void sigthread::init (const char *s) { -#if 0 /* FIXME: Someday we'll need this for inter-thread signalling */ - lock = new_muto (FALSE, s); -#endif + InitializeCriticalSection (&lock); id = GetCurrentThreadId (); } @@ -658,6 +656,8 @@ dll_crt0_1 () cygheap_init (); /* Initialize cygheap muto */ regthread ("main", GetCurrentThreadId ()); + mainthread.init ("mainthread"); // For use in determining if signals + // should be blocked. int envc = 0; char **envp = NULL; @@ -725,9 +725,6 @@ dll_crt0_1 () or attach to the shared data structure if it's already running. */ shared_init (); - mainthread.init ("mainthread"); // For use in determining if signals - // should be blocked. - (void) SetErrorMode (SEM_FAILCRITICALERRORS); /* Initialize the heap. */ diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 4358e6a75..fcdf7c44e 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -23,6 +23,8 @@ details. */ #include "perprocess.h" #include "security.h" +#define CALL_HANDLER_RETRY 20 + char debugger_command[2 * MAX_PATH + 20]; extern "C" { @@ -680,11 +682,6 @@ interrupt_on_return (sigthread *th, int sig, struct sigaction& siga, void *handl if (*addr_retaddr == thestack.sf.AddrReturn.Offset) { interrupt_setup (sig, siga, handler, *addr_retaddr, addr_retaddr); - if (ebp != th->frame) - { - sigsave.sig = 0; - break; - } *addr_retaddr = (DWORD) sigdelayed; } return 1; @@ -701,8 +698,6 @@ set_sig_errno (int e) // sigproc_printf ("errno %d", e); } -#define SUSPEND_TRIES 10000 - static int call_handler (int sig, struct sigaction& siga, void *handler) { @@ -710,28 +705,24 @@ call_handler (int sig, struct sigaction& siga, void *handler) bool interrupted = 0; HANDLE hth = NULL; int res; - sigthread *th; - -#if 0 - mainthread.lock->acquire (); -#endif + sigthread *th = NULL; // Initialization needed to shut up gcc if (sigsave.sig) goto set_pending; - for (int i = 0; !interrupted && i < 10; i++) + for (int i = 0; !interrupted && i < CALL_HANDLER_RETRY; i++) { + EnterCriticalSection (&mainthread.lock); if (mainthread.frame) th = &mainthread; else { - int i; + LeaveCriticalSection (&mainthread.lock); + th = NULL; - #if 0 - mainthread.lock->release (); - #endif hth = myself->getthread2signal (); + /* Suspend the thread which will receive the signal. But first ensure that this thread doesn't have any mutos. (FIXME: Someday we should just grab all of the mutos rather than checking for them) @@ -742,64 +733,54 @@ call_handler (int sig, struct sigaction& siga, void *handler) noticeable delays? If the thread is already suspended (which can occur when a program is stopped) then just queue the signal. */ - for (i = 0; i < SUSPEND_TRIES; i++) - { - sigproc_printf ("suspending mainthread"); - res = SuspendThread (hth); - /* Just set pending if thread is already suspended */ - if (res) - goto set_pending; + sigproc_printf ("suspending mainthread"); + res = SuspendThread (hth); - muto *m; - /* FIXME: Make multi-thread aware */ - for (m = muto_start.next; m != NULL; m = m->next) - if (m->unstable () || m->owner () == mainthread.id) - goto owns_muto; - - #if 0 - mainthread.lock->acquire (); - #endif - if (mainthread.frame) - { - th = &mainthread; - goto next; - } - #if 0 - mainthread.lock->release (); - #endif - - cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; - if (!GetThreadContext (hth, &cx)) - { - system_printf ("couldn't get context of main thread, %E"); - goto out; - } - - if (interruptible (cx.Eip, 1)) - break; - - sigproc_printf ("suspended thread in a strange state pc %p, sp %p", - cx.Eip, cx.Esp); - goto resume_thread; - - owns_muto: - sigproc_printf ("suspended thread owns a muto (%s)", m->name); - - resume_thread: - ResumeThread (hth); - Sleep (0); - } - - if (i >= SUSPEND_TRIES) + /* Just set pending if thread is already suspended */ + if (res) goto set_pending; - sigproc_printf ("SuspendThread returned %d", res); + muto *m; + /* FIXME: Make multi-thread aware */ + for (m = muto_start.next; m != NULL; m = m->next) + if (m->unstable () || m->owner () == mainthread.id) + { + sigproc_printf ("suspended thread owns a muto (%s)", m->name); + goto resume_thread; + } + + EnterCriticalSection (&mainthread.lock); + if (mainthread.frame) + { + th = &mainthread; + goto try_to_interrupt; + } + + LeaveCriticalSection (&mainthread.lock); + + cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; + if (!GetThreadContext (hth, &cx)) + system_printf ("couldn't get context of main thread, %E"); + else if (!interruptible (cx.Eip, 1)) + sigproc_printf ("suspended thread in a strange state pc %p, sp %p", + cx.Eip, cx.Esp); + else + goto try_to_interrupt; + + resume_thread: + ResumeThread (hth); + Sleep (0); + continue; } - next: + try_to_interrupt: if (th) - interrupted = interrupt_on_return (th, sig, siga, handler); + { + interrupted = interrupt_on_return (th, sig, siga, handler); + if (!interrupted) + LeaveCriticalSection (&th->lock); + } else if (interruptible (cx.Eip)) interrupted = interrupt_now (&cx, sig, siga, handler); else @@ -821,7 +802,9 @@ set_pending: proc_subproc (PROC_CLEARWAIT, 1); } -out: + if (th) + LeaveCriticalSection (&th->lock); + if (!hth) sigproc_printf ("modified main-thread stack"); else @@ -830,10 +813,6 @@ out: sigproc_printf ("ResumeThread returned %d", res); } -#if 0 - mainthread.lock->release (); -#endif - sigproc_printf ("returning %d", interrupted); return interrupted; } diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 81ba58b4c..28fec5008 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -258,6 +258,7 @@ proc_subproc (DWORD what, DWORD val) 0, TRUE, DUPLICATE_SAME_ACCESS)) system_printf ("Couldn't duplicate my handle<%p> for pid %d, %E", hMainProc, vchild->pid); vchild->ppid = myself->pid; + vchild->uid = myself->uid; vchild->gid = myself->gid; vchild->pgid = myself->pgid; vchild->sid = myself->sid; diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index 40f518777..2e31e578c 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -39,9 +39,7 @@ struct sigthread { DWORD id; DWORD frame; -#if 0 - muto *lock; // FIXME: Use for multi-thread signalling someday -#endif + CRITICAL_SECTION lock; void init (const char *s); }; @@ -69,7 +67,9 @@ public: { if (st) { + EnterCriticalSection (&st->lock); st->frame = 0; + LeaveCriticalSection (&st->lock); st = NULL; } }