* exceptions.cc (try_to_debug): Prevent recursive spawning of JIT debugger.
Treat special event from debugger as command to continue.
This commit is contained in:
parent
0106a9b755
commit
1d613351e5
|
@ -1,8 +1,13 @@
|
||||||
|
2000-07-04 Vadim Egorov <egorovv@mailandnews.com>
|
||||||
|
|
||||||
|
* exceptions.cc (try_to_debug): Prevent recursive spawning of JIT
|
||||||
|
debugger. Treat special event from debugger as command to continue.
|
||||||
|
|
||||||
Mon Jul 4 19:29:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
Mon Jul 4 19:29:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* poll.cc (poll): Zero out `open_fds' as well.
|
* poll.cc (poll): Zero out `open_fds' as well.
|
||||||
|
|
||||||
Mon Jul 4 19:22:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
Mon Jul 4 1:22:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* include/cygwin/version.h: Bump API minor version to 24.
|
* include/cygwin/version.h: Bump API minor version to 24.
|
||||||
|
|
||||||
|
@ -16,7 +21,7 @@ Mon Jul 4 18:57:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
||||||
* include/poll.h: Ditto.
|
* include/poll.h: Ditto.
|
||||||
* include/sys/poll.h: Ditto.
|
* include/sys/poll.h: Ditto.
|
||||||
* Makefile.in: Add poll.o as dependency.
|
* Makefile.in: Add poll.o as dependency.
|
||||||
* cygwin.din: Add poll and _poll symbols.
|
* cygwin.din: Add poll and _poll symbols.
|
||||||
|
|
||||||
2000-07-04 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
|
2000-07-04 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
|
||||||
|
|
||||||
|
|
|
@ -196,19 +196,19 @@ exception (EXCEPTION_RECORD *e, CONTEXT *in)
|
||||||
class stack_info
|
class stack_info
|
||||||
{
|
{
|
||||||
int first_time; /* True if just starting to iterate. */
|
int first_time; /* True if just starting to iterate. */
|
||||||
int walk (); /* Uses the "old" method */
|
int walk (); /* Uses the "old" method */
|
||||||
char *next_offset () {return *((char **) sf.AddrFrame.Offset);}
|
char *next_offset () {return *((char **) sf.AddrFrame.Offset);}
|
||||||
public:
|
public:
|
||||||
STACKFRAME sf; /* For storing the stack information */
|
STACKFRAME sf; /* For storing the stack information */
|
||||||
void init (DWORD); /* Called the first time that stack info is needed */
|
void init (DWORD); /* Called the first time that stack info is needed */
|
||||||
stack_info (): first_time(1) {}
|
stack_info (): first_time (1) {}
|
||||||
|
|
||||||
/* Postfix ++ iterates over the stack, returning zero when nothing is left. */
|
/* Postfix ++ iterates over the stack, returning zero when nothing is left. */
|
||||||
int operator ++(int) { return this->walk (); }
|
int operator ++(int) { return this->walk (); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The number of parameters used in STACKFRAME */
|
/* The number of parameters used in STACKFRAME */
|
||||||
#define NPARAMS (sizeof(thestack.sf.Params) / sizeof(thestack.sf.Params[0]))
|
#define NPARAMS (sizeof (thestack.sf.Params) / sizeof (thestack.sf.Params[0]))
|
||||||
|
|
||||||
/* This is the main stack frame info for this process. */
|
/* This is the main stack frame info for this process. */
|
||||||
static NO_COPY stack_info thestack;
|
static NO_COPY stack_info thestack;
|
||||||
|
@ -219,7 +219,7 @@ void
|
||||||
stack_info::init (DWORD ebp)
|
stack_info::init (DWORD ebp)
|
||||||
{
|
{
|
||||||
first_time = 1;
|
first_time = 1;
|
||||||
memset (&sf, 0, sizeof(sf));
|
memset (&sf, 0, sizeof (sf));
|
||||||
sf.AddrFrame.Offset = ebp;
|
sf.AddrFrame.Offset = ebp;
|
||||||
sf.AddrPC.Offset = ((DWORD *) ebp)[1];
|
sf.AddrPC.Offset = ((DWORD *) ebp)[1];
|
||||||
sf.AddrFrame.Mode = AddrModeFlat;
|
sf.AddrFrame.Mode = AddrModeFlat;
|
||||||
|
@ -277,7 +277,7 @@ stack (CONTEXT *cx)
|
||||||
|
|
||||||
/* Temporary (?) function for external callers to get a stack dump */
|
/* Temporary (?) function for external callers to get a stack dump */
|
||||||
extern "C" void
|
extern "C" void
|
||||||
cygwin_stackdump()
|
cygwin_stackdump ()
|
||||||
{
|
{
|
||||||
CONTEXT c;
|
CONTEXT c;
|
||||||
c.ContextFlags = CONTEXT_FULL;
|
c.ContextFlags = CONTEXT_FULL;
|
||||||
|
@ -287,6 +287,8 @@ cygwin_stackdump()
|
||||||
|
|
||||||
static int NO_COPY keep_looping = 0;
|
static int NO_COPY keep_looping = 0;
|
||||||
|
|
||||||
|
#define TIME_TO_WAIT_FOR_DEBUGGER 10000
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
try_to_debug ()
|
try_to_debug ()
|
||||||
{
|
{
|
||||||
|
@ -316,6 +318,21 @@ try_to_debug ()
|
||||||
ReleaseMutex (pinfo_mutex);
|
ReleaseMutex (pinfo_mutex);
|
||||||
ReleaseMutex (title_mutex);
|
ReleaseMutex (title_mutex);
|
||||||
|
|
||||||
|
/* prevent recursive exception handling */
|
||||||
|
char* rawenv = GetEnvironmentStrings () ;
|
||||||
|
for (char* p = rawenv; *p != '\0'; p = strchr (p, '\0') + 1)
|
||||||
|
{
|
||||||
|
if (strncmp (p, "CYGWIN=", sizeof ("CYGWIN=") - 1) == 0)
|
||||||
|
{
|
||||||
|
system_printf ("%s", p);
|
||||||
|
char* q = strstr (p, "error_start") ;
|
||||||
|
/* replace 'error_start=...' with '_rror_start=...' */
|
||||||
|
if (q) *q = '_' ;
|
||||||
|
SetEnvironmentVariable ("CYGWIN", p + sizeof ("CYGWIN=")) ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dbg = CreateProcess (NULL,
|
dbg = CreateProcess (NULL,
|
||||||
debugger_command,
|
debugger_command,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -330,14 +347,27 @@ try_to_debug ()
|
||||||
{
|
{
|
||||||
system_printf ("Failed to start debugger: %E");
|
system_printf ("Failed to start debugger: %E");
|
||||||
/* FIXME: need to know handles of all running threads to
|
/* FIXME: need to know handles of all running threads to
|
||||||
resume_all_threads_except (current_thread_id);
|
resume_all_threads_except (current_thread_id);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
char event_name [ sizeof ("cygwin_error_start_event") + 9 ];
|
||||||
|
DWORD win32_pid = GetCurrentProcessId ();
|
||||||
|
__small_sprintf (event_name, "cygwin_error_start_event%x", win32_pid);
|
||||||
|
HANDLE sync_with_dbg = CreateEvent (NULL, TRUE, FALSE, event_name);
|
||||||
keep_looping = 1;
|
keep_looping = 1;
|
||||||
while (keep_looping)
|
while (keep_looping)
|
||||||
Sleep (10000);
|
{
|
||||||
|
if (sync_with_dbg == NULL)
|
||||||
|
Sleep (TIME_TO_WAIT_FOR_DEBUGGER);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (WaitForSingleObject (sync_with_dbg,
|
||||||
|
TIME_TO_WAIT_FOR_DEBUGGER) == WAIT_OBJECT_0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -354,7 +384,7 @@ stackdump (EXCEPTION_RECORD *e, CONTEXT *in)
|
||||||
p++;
|
p++;
|
||||||
else
|
else
|
||||||
p = myself->progname;
|
p = myself->progname;
|
||||||
char corefile[strlen(p) + sizeof(".stackdump")];
|
char corefile[strlen (p) + sizeof (".stackdump")];
|
||||||
__small_sprintf (corefile, "%s.stackdump", p);
|
__small_sprintf (corefile, "%s.stackdump", p);
|
||||||
HANDLE h = CreateFile (corefile, GENERIC_WRITE, 0, &sec_none_nih,
|
HANDLE h = CreateFile (corefile, GENERIC_WRITE, 0, &sec_none_nih,
|
||||||
CREATE_ALWAYS, 0, 0);
|
CREATE_ALWAYS, 0, 0);
|
||||||
|
@ -439,11 +469,11 @@ handle_exceptions (EXCEPTION_RECORD *e, void *, CONTEXT *in, void *)
|
||||||
debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp);
|
debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp);
|
||||||
debug_printf ("In cygwin_except_handler sig = %d at %p", sig, in->Eip);
|
debug_printf ("In cygwin_except_handler sig = %d at %p", sig, in->Eip);
|
||||||
|
|
||||||
if (myself->getsig(sig).sa_mask & SIGTOMASK (sig))
|
if (myself->getsig (sig).sa_mask & SIGTOMASK (sig))
|
||||||
syscall_printf ("signal %d, masked %p", sig, myself->getsig(sig).sa_mask);
|
syscall_printf ("signal %d, masked %p", sig, myself->getsig (sig).sa_mask);
|
||||||
|
|
||||||
debug_printf ("In cygwin_except_handler calling %p",
|
debug_printf ("In cygwin_except_handler calling %p",
|
||||||
myself->getsig(sig).sa_handler);
|
myself->getsig (sig).sa_handler);
|
||||||
|
|
||||||
DWORD *ebp = (DWORD *)in->Esp;
|
DWORD *ebp = (DWORD *)in->Esp;
|
||||||
for (DWORD *bpend = (DWORD *) __builtin_frame_address (0); ebp > bpend; ebp--)
|
for (DWORD *bpend = (DWORD *) __builtin_frame_address (0); ebp > bpend; ebp--)
|
||||||
|
@ -454,9 +484,9 @@ handle_exceptions (EXCEPTION_RECORD *e, void *, CONTEXT *in, void *)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!myself->progname[0]
|
if (!myself->progname[0]
|
||||||
|| (void *) myself->getsig(sig).sa_handler == (void *) SIG_DFL
|
|| (void *) myself->getsig (sig).sa_handler == (void *) SIG_DFL
|
||||||
|| (void *) myself->getsig(sig).sa_handler == (void *) SIG_IGN
|
|| (void *) myself->getsig (sig).sa_handler == (void *) SIG_IGN
|
||||||
|| (void *) myself->getsig(sig).sa_handler == (void *) SIG_ERR)
|
|| (void *) myself->getsig (sig).sa_handler == (void *) SIG_ERR)
|
||||||
{
|
{
|
||||||
static NO_COPY int traced = 0;
|
static NO_COPY int traced = 0;
|
||||||
|
|
||||||
|
@ -476,7 +506,7 @@ handle_exceptions (EXCEPTION_RECORD *e, void *, CONTEXT *in, void *)
|
||||||
/* Another exception could happen while tracing or while exiting.
|
/* Another exception could happen while tracing or while exiting.
|
||||||
Only do this once. */
|
Only do this once. */
|
||||||
if (traced++)
|
if (traced++)
|
||||||
system_printf ("Error while dumping state (probably corrupted stack)");
|
system_printf ("Error while dumping state (probably corrupted stack)");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CONTEXT c = *in;
|
CONTEXT c = *in;
|
||||||
|
@ -572,7 +602,7 @@ interruptible (DWORD pc, int testvalid = 0)
|
||||||
else if (!GetModuleFileName (h, checkdir, windows_system_directory_length + 2))
|
else if (!GetModuleFileName (h, checkdir, windows_system_directory_length + 2))
|
||||||
res = 0;
|
res = 0;
|
||||||
else
|
else
|
||||||
res = !strncasematch (windows_system_directory, checkdir,
|
res = !strncasematch (windows_system_directory, checkdir,
|
||||||
windows_system_directory_length);
|
windows_system_directory_length);
|
||||||
minimal_printf ("h %p", h);
|
minimal_printf ("h %p", h);
|
||||||
# undef h
|
# undef h
|
||||||
|
@ -601,7 +631,7 @@ interrupt_now (CONTEXT *ctx, int sig, struct sigaction& siga, void *handler)
|
||||||
{
|
{
|
||||||
interrupt_setup (sig, siga, handler, ctx->Eip, 0);
|
interrupt_setup (sig, siga, handler, ctx->Eip, 0);
|
||||||
ctx->Eip = (DWORD) sigdelayed;
|
ctx->Eip = (DWORD) sigdelayed;
|
||||||
SetThreadContext (myself->getthread2signal(), ctx); /* Restart the thread */
|
SetThreadContext (myself->getthread2signal (), ctx); /* Restart the thread */
|
||||||
}
|
}
|
||||||
|
|
||||||
void __cdecl
|
void __cdecl
|
||||||
|
@ -617,7 +647,7 @@ signal_fixup_after_fork ()
|
||||||
set_process_mask (sigsave.oldmask);
|
set_process_mask (sigsave.oldmask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
interrupt_on_return (DWORD ebp, int sig, struct sigaction& siga, void *handler)
|
interrupt_on_return (DWORD ebp, int sig, struct sigaction& siga, void *handler)
|
||||||
{
|
{
|
||||||
|
@ -723,7 +753,7 @@ call_handler (int sig, struct sigaction& siga, void *handler)
|
||||||
|
|
||||||
owns_muto:
|
owns_muto:
|
||||||
sigproc_printf ("suspended thread owns a muto (%s)", m->name);
|
sigproc_printf ("suspended thread owns a muto (%s)", m->name);
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
goto set_pending;
|
goto set_pending;
|
||||||
|
|
||||||
|
@ -755,7 +785,7 @@ next:
|
||||||
res = SetEvent (signal_arrived); // For an EINTR case
|
res = SetEvent (signal_arrived); // For an EINTR case
|
||||||
sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res);
|
sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res);
|
||||||
/* Clear any waiting threads prior to dispatching to handler function */
|
/* Clear any waiting threads prior to dispatching to handler function */
|
||||||
proc_subproc(PROC_CLEARWAIT, 1);
|
proc_subproc (PROC_CLEARWAIT, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -798,7 +828,7 @@ ctrl_c_handler (DWORD type)
|
||||||
sig_send (NULL, SIGHUP);
|
sig_send (NULL, SIGHUP);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
tty_min *t = cygwin_shared->tty.get_tty(myself->ctty);
|
tty_min *t = cygwin_shared->tty.get_tty (myself->ctty);
|
||||||
/* Ignore this if we're not the process group lead since it should be handled
|
/* Ignore this if we're not the process group lead since it should be handled
|
||||||
*by* the process group leader. */
|
*by* the process group leader. */
|
||||||
if (t->getpgid () != myself->pid ||
|
if (t->getpgid () != myself->pid ||
|
||||||
|
@ -858,7 +888,7 @@ sig_handle_tty_stop (int sig)
|
||||||
*/
|
*/
|
||||||
if (my_parent_is_alive ())
|
if (my_parent_is_alive ())
|
||||||
{
|
{
|
||||||
pinfo *parent = procinfo(myself->ppid);
|
pinfo *parent = procinfo (myself->ppid);
|
||||||
sig_send (parent, __SIGCHILDSTOPPED);
|
sig_send (parent, __SIGCHILDSTOPPED);
|
||||||
}
|
}
|
||||||
sigproc_printf ("process %d stopped by signal %d, parent_alive %p",
|
sigproc_printf ("process %d stopped by signal %d, parent_alive %p",
|
||||||
|
@ -876,7 +906,7 @@ sig_handle (int sig)
|
||||||
|
|
||||||
sigproc_printf ("signal %d", sig);
|
sigproc_printf ("signal %d", sig);
|
||||||
|
|
||||||
struct sigaction thissig = myself->getsig(sig);
|
struct sigaction thissig = myself->getsig (sig);
|
||||||
void *handler = (void *) thissig.sa_handler;
|
void *handler = (void *) thissig.sa_handler;
|
||||||
|
|
||||||
myself->rusage_self.ru_nsignals++;
|
myself->rusage_self.ru_nsignals++;
|
||||||
|
@ -969,8 +999,8 @@ exit_sig:
|
||||||
TerminateThread (hMainThread, 0);
|
TerminateThread (hMainThread, 0);
|
||||||
/* FIXME: This just works around the problem so that we don't attempt to
|
/* FIXME: This just works around the problem so that we don't attempt to
|
||||||
use a resource lock when exiting. */
|
use a resource lock when exiting. */
|
||||||
user_data->resourcelocks->Delete();
|
user_data->resourcelocks->Delete ();
|
||||||
user_data->resourcelocks->Init();
|
user_data->resourcelocks->Init ();
|
||||||
do_exit (EXIT_SIGNAL | (sig << 8));
|
do_exit (EXIT_SIGNAL | (sig << 8));
|
||||||
/* Never returns */
|
/* Never returns */
|
||||||
}
|
}
|
||||||
|
@ -1053,7 +1083,7 @@ reset_signal_arrived ()
|
||||||
sigproc_printf ("reset signal_arrived");
|
sigproc_printf ("reset signal_arrived");
|
||||||
}
|
}
|
||||||
|
|
||||||
void unused_sig_wrapper()
|
void unused_sig_wrapper ()
|
||||||
{
|
{
|
||||||
/* Signal cleanup stuff. Cleans up stack (too bad that we didn't
|
/* Signal cleanup stuff. Cleans up stack (too bad that we didn't
|
||||||
prototype signal handlers as __stdcall), calls _set_process_mask
|
prototype signal handlers as __stdcall), calls _set_process_mask
|
||||||
|
@ -1120,6 +1150,6 @@ ___siglast:
|
||||||
" : "=m" (sigsave.sig) : "m" (&_impure_ptr->_errno),
|
" : "=m" (sigsave.sig) : "m" (&_impure_ptr->_errno),
|
||||||
"g" (sigsave.retaddr), "g" (sigsave.oldmask), "g" (sigsave.sig),
|
"g" (sigsave.retaddr), "g" (sigsave.oldmask), "g" (sigsave.sig),
|
||||||
"g" (sigsave.func), "o" (pid_offset), "g" (sigsave.saved_errno)
|
"g" (sigsave.func), "o" (pid_offset), "g" (sigsave.saved_errno)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue