3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
21 #include "exceptions.h"
27 #include "shared_info.h"
28 #include "perprocess.h"
34 #include "child_info.h"
36 #define CALL_HANDLER_RETRY 20
38 char debugger_command[2 * CYG_MAX_PATH + 20];
41 extern void sigdelayed ();
44 extern child_info_spawn *chExeced;
45 int NO_COPY sigExeced;
47 static BOOL WINAPI ctrl_c_handler (DWORD);
48 char windows_system_directory[1024];
49 static size_t windows_system_directory_length;
51 /* This is set to indicate that we have already exited. */
53 static NO_COPY int exit_already = 0;
54 static muto NO_COPY mask_sync;
63 { X (STATUS_ABANDONED_WAIT_0) },
64 { X (STATUS_ACCESS_VIOLATION) },
65 { X (STATUS_ARRAY_BOUNDS_EXCEEDED) },
66 { X (STATUS_BREAKPOINT) },
67 { X (STATUS_CONTROL_C_EXIT) },
68 { X (STATUS_DATATYPE_MISALIGNMENT) },
69 { X (STATUS_FLOAT_DENORMAL_OPERAND) },
70 { X (STATUS_FLOAT_DIVIDE_BY_ZERO) },
71 { X (STATUS_FLOAT_INEXACT_RESULT) },
72 { X (STATUS_FLOAT_INVALID_OPERATION) },
73 { X (STATUS_FLOAT_OVERFLOW) },
74 { X (STATUS_FLOAT_STACK_CHECK) },
75 { X (STATUS_FLOAT_UNDERFLOW) },
76 { X (STATUS_GUARD_PAGE_VIOLATION) },
77 { X (STATUS_ILLEGAL_INSTRUCTION) },
78 { X (STATUS_INTEGER_DIVIDE_BY_ZERO) },
79 { X (STATUS_INTEGER_OVERFLOW) },
80 { X (STATUS_INVALID_DISPOSITION) },
81 { X (STATUS_IN_PAGE_ERROR) },
82 { X (STATUS_NONCONTINUABLE_EXCEPTION) },
83 { X (STATUS_NO_MEMORY) },
84 { X (STATUS_PENDING) },
85 { X (STATUS_PRIVILEGED_INSTRUCTION) },
86 { X (STATUS_SINGLE_STEP) },
87 { X (STATUS_STACK_OVERFLOW) },
88 { X (STATUS_TIMEOUT) },
89 { X (STATUS_USER_APC) },
90 { X (STATUS_WAIT_0) },
95 /* Initialization code. */
98 dummy_ctrl_c_handler (DWORD)
104 init_console_handler (bool install_handler)
108 SetConsoleCtrlHandler (ctrl_c_handler, FALSE);
109 if (wincap.has_null_console_handler_routine ())
110 SetConsoleCtrlHandler (NULL, FALSE);
112 res = SetConsoleCtrlHandler (ctrl_c_handler, TRUE);
113 else if (wincap.has_null_console_handler_routine ())
114 res = SetConsoleCtrlHandler (NULL, TRUE);
116 res = SetConsoleCtrlHandler (dummy_ctrl_c_handler, TRUE);
118 system_printf ("SetConsoleCtrlHandler failed, %E");
122 error_start_init (const char *buf)
126 debugger_command[0] = '\0';
130 char pgm[CYG_MAX_PATH];
131 if (!GetModuleFileName (NULL, pgm, CYG_MAX_PATH))
132 strcpy (pgm, "cygwin1.dll");
133 for (char *p = strchr (pgm, '\\'); p; p = strchr (p, '\\'))
136 __small_sprintf (debugger_command, "%s \"%s\"", buf, pgm);
140 open_stackdumpfile ()
142 if (myself->progname[0])
145 /* write to progname.stackdump if possible */
146 if (!myself->progname[0])
148 else if ((p = strrchr (myself->progname, '\\')))
151 p = myself->progname;
152 char corefile[strlen (p) + sizeof (".stackdump")];
153 __small_sprintf (corefile, "%s.stackdump", p);
154 HANDLE h = CreateFile (corefile, GENERIC_WRITE, 0, &sec_none_nih,
155 CREATE_ALWAYS, 0, 0);
156 if (h != INVALID_HANDLE_VALUE)
158 if (!myself->cygstarted)
159 system_printf ("Dumping stack trace to %s", corefile);
161 debug_printf ("Dumping stack trace to %s", corefile);
162 SetStdHandle (STD_ERROR_HANDLE, h);
167 /* Utilities for dumping the stack, etc. */
170 exception (EXCEPTION_RECORD *e, CONTEXT *in)
172 const char *exception_name = NULL;
176 for (int i = 0; status_info[i].name; i++)
178 if (status_info[i].code == e->ExceptionCode)
180 exception_name = status_info[i].name;
187 small_printf ("Exception: %s at eip=%08x\r\n", exception_name, in->Eip);
189 small_printf ("Signal %d at eip=%08x\r\n", e->ExceptionCode, in->Eip);
190 small_printf ("eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\r\n",
191 in->Eax, in->Ebx, in->Ecx, in->Edx, in->Esi, in->Edi);
192 small_printf ("ebp=%08x esp=%08x program=%s, pid %u, thread %s\r\n",
193 in->Ebp, in->Esp, myself->progname, myself->pid, cygthread::name ());
194 small_printf ("cs=%04x ds=%04x es=%04x fs=%04x gs=%04x ss=%04x\r\n",
195 in->SegCs, in->SegDs, in->SegEs, in->SegFs, in->SegGs, in->SegSs);
198 /* A class for manipulating the stack. */
201 int walk (); /* Uses the "old" method */
202 char *next_offset () {return *((char **) sf.AddrFrame.Offset);}
206 STACKFRAME sf; /* For storing the stack information */
207 void init (DWORD, bool, bool); /* Called the first time that stack info is needed */
209 /* Postfix ++ iterates over the stack, returning zero when nothing is left. */
210 int operator ++(int) { return walk (); }
213 /* The number of parameters used in STACKFRAME */
214 #define NPARAMS (sizeof (thestack.sf.Params) / sizeof (thestack.sf.Params[0]))
216 /* This is the main stack frame info for this process. */
217 static NO_COPY stack_info thestack;
219 /* Initialize everything needed to start iterating. */
221 stack_info::init (DWORD ebp, bool wantargs, bool goodframe)
223 # define debp ((DWORD *) ebp)
224 memset (&sf, 0, sizeof (sf));
226 sf.AddrFrame.Offset = ebp;
230 sf.AddrFrame.Offset = (DWORD) &dummy_frame;
232 sf.AddrReturn.Offset = debp[1];
233 sf.AddrFrame.Mode = AddrModeFlat;
238 /* Walk the stack by looking at successive stored 'bp' frames.
239 This is not foolproof. */
244 if ((ebp = (char **) next_offset ()) == NULL)
247 sf.AddrFrame.Offset = (DWORD) ebp;
248 sf.AddrPC.Offset = sf.AddrReturn.Offset;
250 if (!sf.AddrPC.Offset)
251 return 0; /* stack frames are exhausted */
253 /* The return address always follows the stack pointer */
254 sf.AddrReturn.Offset = (DWORD) *++ebp;
257 /* The arguments follow the return address */
258 for (unsigned i = 0; i < NPARAMS; i++)
259 sf.Params[i] = (DWORD) *++ebp;
265 stackdump (DWORD ebp, int open_file, bool isexception)
267 extern unsigned long rlim_core;
268 static bool already_dumped;
270 if (rlim_core == 0UL || (open_file && already_dumped))
274 open_stackdumpfile ();
276 already_dumped = true;
280 thestack.init (ebp, 1, !isexception); /* Initialize from the input CONTEXT */
281 small_printf ("Stack trace:\r\nFrame Function Args\r\n");
282 for (i = 0; i < 16 && thestack++; i++)
284 small_printf ("%08x %08x ", thestack.sf.AddrFrame.Offset,
285 thestack.sf.AddrPC.Offset);
286 for (unsigned j = 0; j < NPARAMS; j++)
287 small_printf ("%s%08x", j == 0 ? " (" : ", ", thestack.sf.Params[j]);
288 small_printf (")\r\n");
290 small_printf ("End of stack trace%s\n",
291 i == 16 ? " (more stack frames may be present)" : "");
295 inside_kernel (CONTEXT *cx)
298 MEMORY_BASIC_INFORMATION m;
303 memset (&m, 0, sizeof m);
304 if (!VirtualQuery ((LPCVOID) cx->Eip, &m, sizeof m))
305 sigproc_printf ("couldn't get memory info, pc %p, %E", cx->Eip);
307 char *checkdir = (char *) alloca (windows_system_directory_length + 4);
308 memset (checkdir, 0, sizeof (checkdir));
310 # define h ((HMODULE) m.AllocationBase)
311 /* Apparently Windows 95 can sometimes return bogus addresses from
312 GetThreadContext. These resolve to a strange allocation base.
313 These should *never* be treated as interruptible. */
314 if (!h || m.State != MEM_COMMIT)
316 else if (h == user_data->hmodule)
318 else if (!GetModuleFileName (h, checkdir, windows_system_directory_length + 2))
321 res = strncasematch (windows_system_directory, checkdir,
322 windows_system_directory_length);
323 sigproc_printf ("pc %p, h %p, inside_kernel %d", cx->Eip, h, res);
328 /* Temporary (?) function for external callers to get a stack dump */
333 c.ContextFlags = CONTEXT_FULL;
334 GetThreadContext (GetCurrentThread (), &c);
335 stackdump (c.Ebp, 0, 0);
338 #define TIME_TO_WAIT_FOR_DEBUGGER 10000
341 try_to_debug (bool waitloop)
343 debug_printf ("debugger_command '%s'", debugger_command);
344 if (*debugger_command == '\0')
346 if (being_debugged ())
348 extern void break_here ();
353 __small_sprintf (strchr (debugger_command, '\0'), " %u", GetCurrentProcessId ());
355 LONG prio = GetThreadPriority (GetCurrentThread ());
356 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
357 PROCESS_INFORMATION pi = {NULL, 0, 0, 0};
359 STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
360 si.lpReserved = NULL;
365 /* FIXME: need to know handles of all running threads to
366 suspend_all_threads_except (current_thread_id);
369 /* if any of these mutexes is owned, we will fail to start any cygwin app
370 until trapped app exits */
372 lock_ttys::release ();
374 /* prevent recursive exception handling */
375 char* rawenv = GetEnvironmentStrings () ;
376 for (char* p = rawenv; *p != '\0'; p = strchr (p, '\0') + 1)
378 if (strncmp (p, "CYGWIN=", strlen ("CYGWIN=")) == 0)
380 char* q = strstr (p, "error_start") ;
381 /* replace 'error_start=...' with '_rror_start=...' */
385 SetEnvironmentVariable ("CYGWIN", p + strlen ("CYGWIN=")) ;
391 console_printf ("*** starting debugger for pid %u, tid %u\n",
392 cygwin_pid (GetCurrentProcessId ()), GetCurrentThreadId ());
394 dbg = CreateProcess (NULL,
399 CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,
406 system_printf ("Failed to start debugger, %E");
411 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_IDLE);
412 while (!being_debugged ())
413 low_priority_sleep (0);
417 console_printf ("*** continuing pid %u from debugger call (%d)\n",
418 cygwin_pid (GetCurrentProcessId ()), dbg);
420 SetThreadPriority (GetCurrentThread (), prio);
424 extern "C" DWORD __stdcall RtlUnwind (void *, void *, void *, DWORD);
425 static void __stdcall rtl_unwind (exception_list *, PEXCEPTION_RECORD) __attribute__ ((noinline, regparm (3)));
427 rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
437 call _RtlUnwind@16 \n\
442 ": : "r" (frame), "r" (e));
445 /* Main exception handler. */
447 extern "C" char *__progname;
449 _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void *)
451 static bool NO_COPY debugging;
452 static int NO_COPY recursed;
453 _cygtls& me = _my_tls;
455 if (debugging && ++debugging < 500000)
457 SetThreadPriority (hMainThread, THREAD_PRIORITY_NORMAL);
461 /* If we've already exited, don't do anything here. Returning 1
462 tells Windows to keep looking for an exception handler. */
463 if (exit_already || e->ExceptionFlags)
467 si.si_code = SI_KERNEL;
468 /* Coerce win32 value to posix value. */
469 switch (e->ExceptionCode)
471 case STATUS_FLOAT_DENORMAL_OPERAND:
472 case STATUS_FLOAT_DIVIDE_BY_ZERO:
473 case STATUS_FLOAT_INVALID_OPERATION:
474 case STATUS_FLOAT_STACK_CHECK:
475 si.si_signo = SIGFPE;
476 si.si_code = FPE_FLTSUB;
478 case STATUS_FLOAT_INEXACT_RESULT:
479 si.si_signo = SIGFPE;
480 si.si_code = FPE_FLTRES;
482 case STATUS_FLOAT_OVERFLOW:
483 si.si_signo = SIGFPE;
484 si.si_code = FPE_FLTOVF;
486 case STATUS_FLOAT_UNDERFLOW:
487 si.si_signo = SIGFPE;
488 si.si_code = FPE_FLTUND;
490 case STATUS_INTEGER_DIVIDE_BY_ZERO:
491 si.si_signo = SIGFPE;
492 si.si_code = FPE_INTDIV;
494 case STATUS_INTEGER_OVERFLOW:
495 si.si_signo = SIGFPE;
496 si.si_code = FPE_INTOVF;
499 case STATUS_ILLEGAL_INSTRUCTION:
500 si.si_signo = SIGILL;
501 si.si_code = ILL_ILLOPC;
504 case STATUS_PRIVILEGED_INSTRUCTION:
505 si.si_signo = SIGILL;
506 si.si_code = ILL_PRVOPC;
509 case STATUS_NONCONTINUABLE_EXCEPTION:
510 si.si_signo = SIGILL;
511 si.si_code = ILL_ILLADR;
515 si.si_signo = SIGALRM;
518 case STATUS_GUARD_PAGE_VIOLATION:
519 si.si_signo = SIGBUS;
520 si.si_code = BUS_OBJERR;
523 case STATUS_DATATYPE_MISALIGNMENT:
524 si.si_signo = SIGBUS;
525 si.si_code = BUS_ADRALN;
528 case STATUS_ACCESS_VIOLATION:
529 switch (mmap_is_attached_or_noreserve_page (e->ExceptionInformation[1]))
531 case 2: /* MAP_NORESERVE page, now commited. */
533 case 1: /* MAP_NORESERVE page, commit failed, or
534 access to mmap page beyond EOF. */
535 si.si_signo = SIGBUS;
536 si.si_code = BUS_OBJERR;
539 MEMORY_BASIC_INFORMATION m;
540 VirtualQuery ((PVOID) e->ExceptionInformation[1], &m, sizeof m);
541 si.si_signo = SIGSEGV;
542 si.si_code = m.State == MEM_FREE ? SEGV_MAPERR : SEGV_ACCERR;
547 case STATUS_ARRAY_BOUNDS_EXCEEDED:
548 case STATUS_IN_PAGE_ERROR:
549 case STATUS_NO_MEMORY:
550 case STATUS_INVALID_DISPOSITION:
551 case STATUS_STACK_OVERFLOW:
552 si.si_signo = SIGSEGV;
553 si.si_code = SEGV_MAPERR;
556 case STATUS_CONTROL_C_EXIT:
557 si.si_signo = SIGINT;
560 case STATUS_INVALID_HANDLE:
561 /* CloseHandle will throw this exception if it is given an
562 invalid handle. We don't care about the exception; we just
563 want CloseHandle to return an error. This can be revisited
564 if gcc ever supports Windows style structured exception
569 /* If we don't recognize the exception, we have to assume that
570 we are doing structured exception handling, and we let
571 something else handle it. */
575 rtl_unwind (frame, e);
577 debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp);
578 debug_printf ("In cygwin_except_handler sig %d at %p", si.si_signo, in->Eip);
580 if (global_sigs[si.si_signo].sa_mask & SIGTOMASK (si.si_signo))
581 syscall_printf ("signal %d, masked %p", si.si_signo,
582 global_sigs[si.si_signo].sa_mask);
584 debug_printf ("In cygwin_except_handler calling %p",
585 global_sigs[si.si_signo].sa_handler);
587 DWORD *ebp = (DWORD *) in->Esp;
588 for (DWORD *bpend = (DWORD *) __builtin_frame_address (0); ebp > bpend; ebp--)
589 if (*ebp == in->SegCs && ebp[-1] == in->Eip)
595 if (me.fault_guarded ())
596 me.return_from_fault ();
598 me.copy_context (in);
599 if (!cygwin_finished_initializing
601 || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL
602 || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN
603 || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR)
605 /* Print the exception to the console */
606 if (!myself->cygstarted)
607 for (int i = 0; status_info[i].name; i++)
608 if (status_info[i].code == e->ExceptionCode)
610 system_printf ("Exception: %s", status_info[i].name);
614 /* Another exception could happen while tracing or while exiting.
615 Only do this once. */
617 system_printf ("Error while dumping state (probably corrupted stack)");
620 if (try_to_debug (0))
626 open_stackdumpfile ();
628 stackdump ((DWORD) ebp, 0, 1);
631 if (e->ExceptionCode == STATUS_ACCESS_VIOLATION)
634 if (si.si_code == SEGV_ACCERR) /* Address present */
636 if (e->ExceptionInformation[0]) /* Write access */
638 if (!inside_kernel (in)) /* User space */
640 klog (LOG_INFO, "%s[%d]: segfault at %08x rip %08x rsp %08x error %d",
641 __progname, myself->pid,
642 e->ExceptionInformation[1], in->Eip, in->Esp,
643 ((in->Eip >= 0x61000000 && in->Eip < 0x61200000)
644 ? 0 : 4) | (e->ExceptionInformation[0] << 1));
647 me.signal_exit (0x80 | si.si_signo); // Flag signal + core dump
650 si.si_addr = (void *) in->Eip;
651 si.si_errno = si.si_pid = si.si_uid = 0;
653 sig_send (NULL, si, &me); // Signal myself
655 e->ExceptionFlags = 0;
659 /* Utilities to call a user supplied exception handler. */
661 #define SIG_NONMASKABLE (SIGTOMASK (SIGKILL) | SIGTOMASK (SIGSTOP))
663 /* Non-raceable sigsuspend
664 * Note: This implementation is based on the Single UNIX Specification
665 * man page. This indicates that sigsuspend always returns -1 and that
666 * attempts to block unblockable signals will be silently ignored.
667 * This is counter to what appears to be documented in some UNIX
668 * man pages, e.g. Linux.
671 handle_sigsuspend (sigset_t tempmask)
673 if (&_my_tls != _main_tls)
675 cancelable_wait (signal_arrived, INFINITE, cw_cancel_self);
679 sigset_t oldmask = myself->getsigmask (); // Remember for restoration
681 set_signal_mask (tempmask, myself->getsigmask ());
682 sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
684 pthread_testcancel ();
685 cancelable_wait (signal_arrived, INFINITE);
687 set_sig_errno (EINTR); // Per POSIX
689 /* A signal dispatch function will have been added to our stack and will
690 be hit eventually. Set the old mask to be restored when the signal
691 handler returns and indicate its presence by modifying deltamask. */
693 _my_tls.deltamask |= SIG_NONMASKABLE;
694 _my_tls.oldmask = oldmask; // Will be restored by signal handler
698 extern DWORD exec_exit; // Possible exit value for exec
702 sig_handle_tty_stop (int sig)
705 /* Silently ignore attempts to suspend if there is no accommodating
706 cygwin parent to deal with this behavior. */
707 if (!myself->cygstarted)
709 myself->process_state &= ~PID_STOPPED;
713 myself->stopsig = sig;
714 myself->alert_parent (sig);
715 sigproc_printf ("process %d stopped by signal %d", myself->pid, sig);
718 w4[1] = signal_arrived;
719 switch (WaitForMultipleObjects (2, w4, TRUE, INFINITE))
722 case WAIT_OBJECT_0 + 1:
723 reset_signal_arrived ();
724 myself->alert_parent (SIGCONT);
727 api_fatal ("WaitSingleObject failed, %E");
735 _cygtls::interrupt_now (CONTEXT *cx, int sig, void *handler,
736 struct sigaction& siga)
740 if (incyg || spinning || locked () || inside_kernel (cx))
744 push ((__stack_t) cx->Eip);
745 interrupt_setup (sig, handler, siga);
747 SetThreadContext (*this, cx); /* Restart the thread in a new location */
754 _cygtls::interrupt_setup (int sig, void *handler, struct sigaction& siga)
756 push ((__stack_t) sigdelayed);
757 deltamask = siga.sa_mask & ~SIG_NONMASKABLE;
758 sa_flags = siga.sa_flags;
759 func = (void (*) (int)) handler;
760 if (siga.sa_flags & SA_RESETHAND)
761 siga.sa_handler = SIG_DFL;
762 saved_errno = -1; // Flag: no errno to save
763 if (handler == sig_handle_tty_stop)
766 myself->process_state |= PID_STOPPED;
769 this->sig = sig; // Should always be last thing set to avoid a race
780 /* Clear any waiting threads prior to dispatching to handler function */
781 int res = SetEvent (signal_arrived); // For an EINTR case
782 proc_subproc (PROC_CLEARWAIT, 1);
783 sigproc_printf ("armed signal_arrived %p, sig %d, res %d", signal_arrived,
787 extern "C" void __stdcall
788 set_sig_errno (int e)
790 *_my_tls.errno_addr = e;
791 _my_tls.saved_errno = e;
792 // sigproc_printf ("errno %d", e);
795 static int setup_handler (int, void *, struct sigaction&, _cygtls *tls)
796 __attribute__((regparm(3)));
798 setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls)
801 bool interrupted = false;
805 sigproc_printf ("trying to send sig %d but signal %d already armed",
810 for (int i = 0; i < CALL_HANDLER_RETRY; i++)
815 sigproc_printf ("controlled interrupt. stackptr %p, stack %p, stackptr[-1] %p",
816 tls->stackptr, tls->stack, tls->stackptr[-1]);
817 tls->interrupt_setup (sig, handler, siga);
825 HANDLE hth = (HANDLE) *tls;
827 /* Suspend the thread which will receive the signal.
828 For Windows 95, we also have to ensure that the addresses returned by
829 GetThreadContext are valid.
830 If one of these conditions is not true we loop for a fixed number of times
831 since we don't want to stall the signal handler. FIXME: Will this result in
833 If the thread is already suspended (which can occur when a program has called
834 SuspendThread on itself) then just queue the signal. */
837 sigproc_printf ("suspending mainthread");
839 cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
840 if (!GetThreadContext (hth, &cx))
841 memset (&cx, 0, sizeof cx);
842 sigproc_printf ("suspending mainthread PC %p", cx.Eip);
844 res = SuspendThread (hth);
845 /* Just set pending if thread is already suspended */
851 cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
852 if (!GetThreadContext (hth, &cx))
853 system_printf ("couldn't get context of main thread, %E");
855 interrupted = tls->interrupt_now (&cx, sig, handler, siga);
857 res = ResumeThread (hth);
861 sigproc_printf ("couldn't interrupt. trying again.");
862 low_priority_sleep (0);
866 sigproc_printf ("signal %d %sdelivered", sig, interrupted ? "" : "not ");
871 has_visible_window_station ()
877 /* Check if the process is associated with a visible window station.
878 These are processes running on the local desktop as well as processes
879 running in terminal server sessions.
880 Processes running in a service session not explicitely associated
881 with the desktop (using the "Allow service to interact with desktop"
882 property) are running in an invisible window station. */
883 if ((station_hdl = GetProcessWindowStation ())
884 && GetUserObjectInformationA (station_hdl, UOI_FLAGS, &uof,
886 && (uof.dwFlags & WSF_VISIBLE))
891 /* Keyboard interrupt handler. */
893 ctrl_c_handler (DWORD type)
895 static bool saw_close;
897 if (!cygwin_finished_initializing)
899 if (myself->cygstarted) /* Was this process created by a cygwin process? */
900 return TRUE; /* Yes. Let the parent eventually handle CTRL-C issues. */
901 debug_printf ("exiting with status %p", STATUS_CONTROL_C_EXIT);
902 ExitProcess (STATUS_CONTROL_C_EXIT);
905 _my_tls.remove (INFINITE);
908 if (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT)
909 proc_subproc (PROC_KILLFORKED, 0);
912 /* Return FALSE to prevent an "End task" dialog box from appearing
913 for each Cygwin process window that's open when the computer
914 is shut down or console window is closed. */
916 if (type == CTRL_SHUTDOWN_EVENT)
919 /* Don't send a signal. Only NT service applications and their child
920 processes will receive this event and the services typically already
921 handle the shutdown action when getting the SERVICE_CONTROL_SHUTDOWN
923 sig_send (NULL, SIGTERM);
928 if (myself->ctty != -1)
930 if (type == CTRL_CLOSE_EVENT)
932 sig_send (NULL, SIGHUP);
936 if (!saw_close && type == CTRL_LOGOFF_EVENT)
938 /* The CTRL_LOGOFF_EVENT is sent when *any* user logs off.
939 The below code sends a SIGHUP only if it is not performing the
940 default activity for SIGHUP. Note that it is possible for two
941 SIGHUP signals to arrive if a process group leader is exiting
942 too. Getting this 100% right is saved for a future cygwin mailing
944 if (global_sigs[SIGHUP].sa_handler != SIG_DFL)
946 sig_send (myself_nowait, SIGHUP);
955 chExeced->set_saw_ctrl_c ();
959 /* We're only the process group leader when we have a valid pinfo structure.
960 If we don't have one, then the parent "stub" will handle the signal. */
961 if (!pinfo (cygwin_pid (GetCurrentProcessId ())))
964 tty_min *t = cygwin_shared->tty.get_tty (myself->ctty);
965 /* Ignore this if we're not the process group leader since it should be handled
966 *by* the process group leader. */
967 if (myself->ctty != -1 && t->getpgid () == myself->pid &&
968 (GetTickCount () - t->last_ctrl_c) >= MIN_CTRL_C_SLOP)
969 /* Otherwise we just send a SIGINT to the process group and return TRUE (to indicate
970 that we have handled the signal). At this point, type should be
971 a CTRL_C_EVENT or CTRL_BREAK_EVENT. */
974 /* If intr and quit are both mapped to ^C, send SIGQUIT on ^BREAK */
975 if (type == CTRL_BREAK_EVENT
976 && t->ti.c_cc[VINTR] == 3 && t->ti.c_cc[VQUIT] == 3)
978 t->last_ctrl_c = GetTickCount ();
979 killsys (-myself->pid, sig);
980 t->last_ctrl_c = GetTickCount ();
987 /* Function used by low level sig wrappers. */
988 extern "C" void __stdcall
989 set_process_mask (sigset_t newmask)
991 set_signal_mask (newmask, myself->getsigmask ());
992 sigproc_printf ("mask now %p\n", myself->getsigmask ());
998 /* check that sig is in right range */
999 if (sig < 0 || sig >= NSIG)
1002 syscall_printf ("signal %d out of range", sig);
1005 mask_sync.acquire (INFINITE);
1006 sigset_t mask = myself->getsigmask ();
1007 sigaddset (&mask, sig);
1008 set_signal_mask (mask, myself->getsigmask ());
1009 mask_sync.release ();
1016 /* check that sig is in right range */
1017 if (sig < 0 || sig >= NSIG)
1020 syscall_printf ("signal %d out of range", sig);
1023 mask_sync.acquire (INFINITE);
1024 sigset_t mask = myself->getsigmask ();
1025 sigdelset (&mask, sig);
1026 set_signal_mask (mask, myself->getsigmask ());
1027 mask_sync.release ();
1031 extern "C" _sig_func_ptr
1032 sigset (int sig, _sig_func_ptr func)
1034 sig_dispatch_pending ();
1037 /* check that sig is in right range */
1038 if (sig < 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
1041 syscall_printf ("SIG_ERR = sigset (%d, %p)", sig, func);
1042 return (_sig_func_ptr) SIG_ERR;
1045 mask_sync.acquire (INFINITE);
1046 sigset_t mask = myself->getsigmask ();
1047 /* If sig was in the signal mask return SIG_HOLD, otherwise return the
1048 previous disposition. */
1049 if (sigismember (&mask, sig))
1052 prev = global_sigs[sig].sa_handler;
1053 /* If func is SIG_HOLD, add sig to the signal mask, otherwise set the
1054 disposition to func and remove sig from the signal mask. */
1055 if (func == SIG_HOLD)
1056 sigaddset (&mask, sig);
1059 /* No error checking. The test which could return SIG_ERR has already
1062 sigdelset (&mask, sig);
1064 set_signal_mask (mask, myself->getsigmask ());
1065 mask_sync.release ();
1072 return sigset (sig, SIG_IGN) == SIG_ERR ? -1 : 0;
1075 /* Update the signal mask for this process and return the old mask.
1076 Called from sigdelayed */
1078 set_process_mask_delta ()
1080 mask_sync.acquire (INFINITE);
1081 sigset_t newmask, oldmask;
1083 if (_my_tls.deltamask & SIG_NONMASKABLE)
1084 oldmask = _my_tls.oldmask; /* from handle_sigsuspend */
1086 oldmask = myself->getsigmask ();
1087 newmask = (oldmask | _my_tls.deltamask) & ~SIG_NONMASKABLE;
1088 sigproc_printf ("oldmask %p, newmask %p, deltamask %p", oldmask, newmask,
1090 myself->setsigmask (newmask);
1091 mask_sync.release ();
1095 /* Set the signal mask for this process.
1096 Note that some signals are unmaskable, as in UNIX. */
1097 extern "C" void __stdcall
1098 set_signal_mask (sigset_t newmask, sigset_t& oldmask)
1101 if (&_my_tls == _sig_tls)
1102 small_printf ("********* waiting in signal thread\n");
1104 mask_sync.acquire (INFINITE);
1105 newmask &= ~SIG_NONMASKABLE;
1106 sigset_t mask_bits = oldmask & ~newmask;
1107 sigproc_printf ("oldmask %p, newmask %p, mask_bits %p", oldmask, newmask,
1111 sig_dispatch_pending (true);
1113 sigproc_printf ("not calling sig_dispatch_pending");
1114 mask_sync.release ();
1118 sigpacket::process ()
1121 struct sigaction dummy = global_sigs[SIGSTOP];
1123 if (si.si_signo != SIGCONT)
1124 continue_now = false;
1127 continue_now = myself->process_state & PID_STOPPED;
1128 myself->stopsig = 0;
1129 myself->process_state &= ~PID_STOPPED;
1130 /* Clear pending stop signals */
1131 sig_clear (SIGSTOP);
1132 sig_clear (SIGTSTP);
1133 sig_clear (SIGTTIN);
1134 sig_clear (SIGTTOU);
1139 sigproc_printf ("signal %d processing", si.si_signo);
1140 struct sigaction& thissig = global_sigs[si.si_signo];
1142 myself->rusage_self.ru_nsignals++;
1146 if (!hExeced || (void *) thissig.sa_handler == (void *) SIG_IGN)
1147 handler = (void *) thissig.sa_handler;
1153 if (si.si_signo == SIGKILL)
1155 if (si.si_signo == SIGSTOP)
1157 sig_clear (SIGCONT);
1163 bool insigwait_mask;
1164 if ((masked = ISSTATE (myself, PID_STOPPED)))
1165 insigwait_mask = false;
1167 insigwait_mask = !handler && (tls = _cygtls::find_tls (si.si_signo));
1169 insigwait_mask = sigismember (&tls->sigwait_mask, si.si_signo);
1172 goto thread_specific;
1175 /* nothing to do */;
1176 else if (sigismember (mask, si.si_signo))
1179 masked = sigismember (&tls->sigmask, si.si_signo);
1186 sigproc_printf ("signal %d blocked", si.si_signo);
1191 /* Clear pending SIGCONT on stop signals */
1192 if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
1193 sig_clear (SIGCONT);
1196 if (being_debugged ())
1198 char sigmsg[sizeof (_CYGWIN_SIGNAL_STRING " 0xffffffff")];
1199 __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %p", si.si_signo);
1200 OutputDebugString (sigmsg);
1204 if (handler == (void *) SIG_DFL)
1207 goto thread_specific;
1208 if (si.si_signo == SIGCHLD || si.si_signo == SIGIO || si.si_signo == SIGCONT || si.si_signo == SIGWINCH
1209 || si.si_signo == SIGURG)
1211 sigproc_printf ("default signal %d ignored", si.si_signo);
1213 SetEvent (signal_arrived);
1217 if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
1223 if (handler == (void *) SIG_IGN)
1225 sigproc_printf ("signal %d ignored", si.si_signo);
1229 if (handler == (void *) SIG_ERR)
1232 tls->set_siginfo (this);
1236 /* Eat multiple attempts to STOP */
1237 if (ISSTATE (myself, PID_STOPPED))
1239 handler = (void *) sig_handle_tty_stop;
1243 /* Dispatch to the appropriate function. */
1244 sigproc_printf ("signal %d, about to call %p", si.si_signo, handler);
1245 rc = setup_handler (si.si_signo, handler, thissig, tls);
1250 sigproc_printf ("returning %d", rc);
1254 tls->sig = si.si_signo;
1255 tls->set_siginfo (this);
1256 sigproc_printf ("releasing sigwait for thread");
1257 SetEvent (tls->event);
1261 if (si.si_signo == SIGQUIT || si.si_signo == SIGABRT)
1264 c.ContextFlags = CONTEXT_FULL;
1265 GetThreadContext (hMainThread, &c);
1266 tls->copy_context (&c);
1267 si.si_signo |= 0x80;
1269 sigproc_printf ("signal %d, about to call do_exit", si.si_signo);
1270 tls->signal_exit (si.si_signo); /* never returns */
1273 /* Cover function to `do_exit' to handle exiting even in presence of more
1274 exceptions. We used to call exit, but a SIGSEGV shouldn't cause atexit
1277 _cygtls::signal_exit (int rc)
1281 sigproc_printf ("terminating captive process");
1282 TerminateProcess (hExeced, sigExeced = rc);
1285 signal_debugger (rc & 0x7f);
1286 if ((rc & 0x80) && !try_to_debug ())
1287 stackdump (thread_context.ebp, 1, 1);
1289 lock_process until_exit (true);
1290 if (hExeced || exit_state)
1293 /* Starve other threads in a vain attempt to stop them from doing something
1295 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
1297 user_data->resourcelocks->Delete ();
1298 user_data->resourcelocks->Init ();
1300 sigproc_printf ("about to call do_exit (%x)", rc);
1301 SetEvent (signal_arrived);
1308 mask_sync.init ("mask_sync");
1309 windows_system_directory[0] = '\0';
1310 GetSystemDirectory (windows_system_directory, sizeof (windows_system_directory) - 2);
1311 char *end = strchr (windows_system_directory, '\0');
1312 if (end == windows_system_directory)
1313 api_fatal ("can't find windows system directory");
1314 if (end[-1] != '\\')
1319 windows_system_directory_length = end - windows_system_directory;
1320 debug_printf ("windows_system_directory '%s', windows_system_directory_length %d",
1321 windows_system_directory, windows_system_directory_length);
1331 _cygtls::call_signal_handler ()
1333 int this_sa_flags = 0;
1334 /* Call signal handler. */
1338 this_sa_flags = sa_flags;
1342 reset_signal_arrived ();
1343 sigset_t this_oldmask = set_process_mask_delta ();
1344 int this_errno = saved_errno;
1346 unlock (); // make sure synchronized
1348 if (!(this_sa_flags & SA_SIGINFO))
1350 void (*sigfunc) (int) = func;
1355 siginfo_t thissi = infodata;
1356 void (*sigact) (int, siginfo_t *, void *) = (void (*) (int, siginfo_t *, void *)) func;
1357 /* no ucontext_t information provided yet */
1358 sigact (thissig, &thissi, NULL);
1361 set_signal_mask (this_oldmask, myself->getsigmask ());
1362 if (this_errno >= 0)
1363 set_errno (this_errno);
1366 return this_sa_flags & SA_RESTART;
1369 extern "C" void __stdcall
1370 reset_signal_arrived ()
1372 // NEEDED? WaitForSingleObject (signal_arrived, 10);
1373 ResetEvent (signal_arrived);
1374 sigproc_printf ("reset signal_arrived");
1375 if (_my_tls.stackptr > _my_tls.stack)
1376 debug_printf ("stackptr[-1] %p", _my_tls.stackptr[-1]);
1380 _cygtls::copy_context (CONTEXT *c)
1382 memcpy (&thread_context, c, (&thread_context._internal - (unsigned char *) &thread_context));
1386 _cygtls::signal_debugger (int sig)
1388 if (isinitialized () && being_debugged ())
1390 char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING " ffffffff ffffffff")];
1391 __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %d %p %p", sig, thread_id, &thread_context);
1392 OutputDebugString (sigmsg);