* 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.
This commit is contained in:
Christopher Faylor 2000-11-06 23:12:05 +00:00
parent a42c18f0dd
commit c0188ae7cb
5 changed files with 74 additions and 82 deletions

View File

@ -1,3 +1,18 @@
Mon Nov 6 15:11:57 2000 Christopher Faylor <cgf@cygnus.com>
* 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 <jt@dothill.com> Mon Nov 6 11:11:42 2000 Jason Tishler <jt@dothill.com>
* path.cc (mount_info::read_cygdrive_info_from_registry): Use * path.cc (mount_info::read_cygdrive_info_from_registry): Use

View File

@ -613,9 +613,7 @@ char _declspec(dllexport) **__argv = NULL;
void void
sigthread::init (const char *s) sigthread::init (const char *s)
{ {
#if 0 /* FIXME: Someday we'll need this for inter-thread signalling */ InitializeCriticalSection (&lock);
lock = new_muto (FALSE, s);
#endif
id = GetCurrentThreadId (); id = GetCurrentThreadId ();
} }
@ -658,6 +656,8 @@ dll_crt0_1 ()
cygheap_init (); /* Initialize cygheap muto */ cygheap_init (); /* Initialize cygheap muto */
regthread ("main", GetCurrentThreadId ()); regthread ("main", GetCurrentThreadId ());
mainthread.init ("mainthread"); // For use in determining if signals
// should be blocked.
int envc = 0; int envc = 0;
char **envp = NULL; char **envp = NULL;
@ -725,9 +725,6 @@ dll_crt0_1 ()
or attach to the shared data structure if it's already running. */ or attach to the shared data structure if it's already running. */
shared_init (); shared_init ();
mainthread.init ("mainthread"); // For use in determining if signals
// should be blocked.
(void) SetErrorMode (SEM_FAILCRITICALERRORS); (void) SetErrorMode (SEM_FAILCRITICALERRORS);
/* Initialize the heap. */ /* Initialize the heap. */

View File

@ -23,6 +23,8 @@ details. */
#include "perprocess.h" #include "perprocess.h"
#include "security.h" #include "security.h"
#define CALL_HANDLER_RETRY 20
char debugger_command[2 * MAX_PATH + 20]; char debugger_command[2 * MAX_PATH + 20];
extern "C" { 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) if (*addr_retaddr == thestack.sf.AddrReturn.Offset)
{ {
interrupt_setup (sig, siga, handler, *addr_retaddr, addr_retaddr); interrupt_setup (sig, siga, handler, *addr_retaddr, addr_retaddr);
if (ebp != th->frame)
{
sigsave.sig = 0;
break;
}
*addr_retaddr = (DWORD) sigdelayed; *addr_retaddr = (DWORD) sigdelayed;
} }
return 1; return 1;
@ -701,8 +698,6 @@ set_sig_errno (int e)
// sigproc_printf ("errno %d", e); // sigproc_printf ("errno %d", e);
} }
#define SUSPEND_TRIES 10000
static int static int
call_handler (int sig, struct sigaction& siga, void *handler) 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; bool interrupted = 0;
HANDLE hth = NULL; HANDLE hth = NULL;
int res; int res;
sigthread *th; sigthread *th = NULL; // Initialization needed to shut up gcc
#if 0
mainthread.lock->acquire ();
#endif
if (sigsave.sig) if (sigsave.sig)
goto set_pending; 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) if (mainthread.frame)
th = &mainthread; th = &mainthread;
else else
{ {
int i; LeaveCriticalSection (&mainthread.lock);
th = NULL; th = NULL;
#if 0
mainthread.lock->release ();
#endif
hth = myself->getthread2signal (); hth = myself->getthread2signal ();
/* Suspend the thread which will receive the signal. But first ensure that /* 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 this thread doesn't have any mutos. (FIXME: Someday we should just grab
all of the mutos rather than checking for them) all of the mutos rather than checking for them)
@ -742,64 +733,54 @@ call_handler (int sig, struct sigaction& siga, void *handler)
noticeable delays? noticeable delays?
If the thread is already suspended (which can occur when a program is stopped) then If the thread is already suspended (which can occur when a program is stopped) then
just queue the signal. */ 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 */ sigproc_printf ("suspending mainthread");
if (res) res = SuspendThread (hth);
goto set_pending;
muto *m; /* Just set pending if thread is already suspended */
/* FIXME: Make multi-thread aware */ if (res)
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)
goto set_pending; 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) 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)) else if (interruptible (cx.Eip))
interrupted = interrupt_now (&cx, sig, siga, handler); interrupted = interrupt_now (&cx, sig, siga, handler);
else else
@ -821,7 +802,9 @@ set_pending:
proc_subproc (PROC_CLEARWAIT, 1); proc_subproc (PROC_CLEARWAIT, 1);
} }
out: if (th)
LeaveCriticalSection (&th->lock);
if (!hth) if (!hth)
sigproc_printf ("modified main-thread stack"); sigproc_printf ("modified main-thread stack");
else else
@ -830,10 +813,6 @@ out:
sigproc_printf ("ResumeThread returned %d", res); sigproc_printf ("ResumeThread returned %d", res);
} }
#if 0
mainthread.lock->release ();
#endif
sigproc_printf ("returning %d", interrupted); sigproc_printf ("returning %d", interrupted);
return interrupted; return interrupted;
} }

View File

@ -258,6 +258,7 @@ proc_subproc (DWORD what, DWORD val)
0, TRUE, DUPLICATE_SAME_ACCESS)) 0, TRUE, DUPLICATE_SAME_ACCESS))
system_printf ("Couldn't duplicate my handle<%p> for pid %d, %E", hMainProc, vchild->pid); system_printf ("Couldn't duplicate my handle<%p> for pid %d, %E", hMainProc, vchild->pid);
vchild->ppid = myself->pid; vchild->ppid = myself->pid;
vchild->uid = myself->uid;
vchild->gid = myself->gid; vchild->gid = myself->gid;
vchild->pgid = myself->pgid; vchild->pgid = myself->pgid;
vchild->sid = myself->sid; vchild->sid = myself->sid;

View File

@ -39,9 +39,7 @@ struct sigthread
{ {
DWORD id; DWORD id;
DWORD frame; DWORD frame;
#if 0 CRITICAL_SECTION lock;
muto *lock; // FIXME: Use for multi-thread signalling someday
#endif
void init (const char *s); void init (const char *s);
}; };
@ -69,7 +67,9 @@ public:
{ {
if (st) if (st)
{ {
EnterCriticalSection (&st->lock);
st->frame = 0; st->frame = 0;
LeaveCriticalSection (&st->lock);
st = NULL; st = NULL;
} }
} }