summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/exceptions.cc
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2006-02-06 18:24:11 +0000
committerChristopher Faylor <me@cgf.cx>2006-02-06 18:24:11 +0000
commit985d0e68c5f100a6996e43a08eff82981b558ec9 (patch)
tree295dce16374bf028f98c64d09bb3ef61fa89b9ad /winsup/cygwin/exceptions.cc
parent125ff9be63714e51d9668a100193d1e63e645281 (diff)
downloadcygnal-985d0e68c5f100a6996e43a08eff82981b558ec9.tar.gz
cygnal-985d0e68c5f100a6996e43a08eff82981b558ec9.tar.bz2
cygnal-985d0e68c5f100a6996e43a08eff82981b558ec9.zip
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.
Diffstat (limited to 'winsup/cygwin/exceptions.cc')
-rw-r--r--winsup/cygwin/exceptions.cc72
1 files changed, 47 insertions, 25 deletions
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);
+ }
+}