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 ((void *)e->ExceptionInformation[1],
532 case MMAP_NORESERVE_COMMITED:
534 case MMAP_RAISE_SIGBUS: /* MAP_NORESERVE page, commit failed, or
535 access to mmap page beyond EOF. */
536 si.si_signo = SIGBUS;
537 si.si_code = BUS_OBJERR;
540 MEMORY_BASIC_INFORMATION m;
541 VirtualQuery ((PVOID) e->ExceptionInformation[1], &m, sizeof m);
542 si.si_signo = SIGSEGV;
543 si.si_code = m.State == MEM_FREE ? SEGV_MAPERR : SEGV_ACCERR;
548 case STATUS_ARRAY_BOUNDS_EXCEEDED:
549 case STATUS_IN_PAGE_ERROR:
550 case STATUS_NO_MEMORY:
551 case STATUS_INVALID_DISPOSITION:
552 case STATUS_STACK_OVERFLOW:
553 si.si_signo = SIGSEGV;
554 si.si_code = SEGV_MAPERR;
557 case STATUS_CONTROL_C_EXIT:
558 si.si_signo = SIGINT;
561 case STATUS_INVALID_HANDLE:
562 /* CloseHandle will throw this exception if it is given an
563 invalid handle. We don't care about the exception; we just
564 want CloseHandle to return an error. This can be revisited
565 if gcc ever supports Windows style structured exception
570 /* If we don't recognize the exception, we have to assume that
571 we are doing structured exception handling, and we let
572 something else handle it. */
576 rtl_unwind (frame, e);
578 debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp);
579 debug_printf ("In cygwin_except_handler sig %d at %p", si.si_signo, in->Eip);
581 if (global_sigs[si.si_signo].sa_mask & SIGTOMASK (si.si_signo))
582 syscall_printf ("signal %d, masked %p", si.si_signo,
583 global_sigs[si.si_signo].sa_mask);
585 debug_printf ("In cygwin_except_handler calling %p",
586 global_sigs[si.si_signo].sa_handler);
588 DWORD *ebp = (DWORD *) in->Esp;
589 for (DWORD *bpend = (DWORD *) __builtin_frame_address (0); ebp > bpend; ebp--)
590 if (*ebp == in->SegCs && ebp[-1] == in->Eip)
596 if (me.fault_guarded ())
597 me.return_from_fault ();
599 me.copy_context (in);
600 if (!cygwin_finished_initializing
602 || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL
603 || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN
604 || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR)
606 /* Print the exception to the console */
607 if (!myself->cygstarted)
608 for (int i = 0; status_info[i].name; i++)
609 if (status_info[i].code == e->ExceptionCode)
611 system_printf ("Exception: %s", status_info[i].name);
615 /* Another exception could happen while tracing or while exiting.
616 Only do this once. */
618 system_printf ("Error while dumping state (probably corrupted stack)");
621 if (try_to_debug (0))
627 open_stackdumpfile ();
629 stackdump ((DWORD) ebp, 0, 1);
632 if (e->ExceptionCode == STATUS_ACCESS_VIOLATION)
635 if (si.si_code == SEGV_ACCERR) /* Address present */
637 if (e->ExceptionInformation[0]) /* Write access */
639 if (!inside_kernel (in)) /* User space */
641 klog (LOG_INFO, "%s[%d]: segfault at %08x rip %08x rsp %08x error %d",
642 __progname, myself->pid,
643 e->ExceptionInformation[1], in->Eip, in->Esp,
644 ((in->Eip >= 0x61000000 && in->Eip < 0x61200000)
645 ? 0 : 4) | (e->ExceptionInformation[0] << 1));
648 me.signal_exit (0x80 | si.si_signo); // Flag signal + core dump
651 si.si_addr = (void *) in->Eip;
652 si.si_errno = si.si_pid = si.si_uid = 0;
654 sig_send (NULL, si, &me); // Signal myself
656 e->ExceptionFlags = 0;
660 /* Utilities to call a user supplied exception handler. */
662 #define SIG_NONMASKABLE (SIGTOMASK (SIGKILL) | SIGTOMASK (SIGSTOP))
664 /* Non-raceable sigsuspend
665 * Note: This implementation is based on the Single UNIX Specification
666 * man page. This indicates that sigsuspend always returns -1 and that
667 * attempts to block unblockable signals will be silently ignored.
668 * This is counter to what appears to be documented in some UNIX
669 * man pages, e.g. Linux.
672 handle_sigsuspend (sigset_t tempmask)
674 if (&_my_tls != _main_tls)
676 cancelable_wait (signal_arrived, INFINITE, cw_cancel_self);
680 sigset_t oldmask = myself->getsigmask (); // Remember for restoration
682 set_signal_mask (tempmask, myself->getsigmask ());
683 sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
685 pthread_testcancel ();
686 cancelable_wait (signal_arrived, INFINITE);
688 set_sig_errno (EINTR); // Per POSIX
690 /* A signal dispatch function will have been added to our stack and will
691 be hit eventually. Set the old mask to be restored when the signal
692 handler returns and indicate its presence by modifying deltamask. */
694 _my_tls.deltamask |= SIG_NONMASKABLE;
695 _my_tls.oldmask = oldmask; // Will be restored by signal handler
699 extern DWORD exec_exit; // Possible exit value for exec
703 sig_handle_tty_stop (int sig)
706 /* Silently ignore attempts to suspend if there is no accommodating
707 cygwin parent to deal with this behavior. */
708 if (!myself->cygstarted)
710 myself->process_state &= ~PID_STOPPED;
714 myself->stopsig = sig;
715 myself->alert_parent (sig);
716 sigproc_printf ("process %d stopped by signal %d", myself->pid, sig);
719 w4[1] = signal_arrived;
720 switch (WaitForMultipleObjects (2, w4, TRUE, INFINITE))
723 case WAIT_OBJECT_0 + 1:
724 reset_signal_arrived ();
725 myself->alert_parent (SIGCONT);
728 api_fatal ("WaitSingleObject failed, %E");
736 _cygtls::interrupt_now (CONTEXT *cx, int sig, void *handler,
737 struct sigaction& siga)
741 if (incyg || spinning || locked () || inside_kernel (cx))
745 push ((__stack_t) cx->Eip);
746 interrupt_setup (sig, handler, siga);
748 SetThreadContext (*this, cx); /* Restart the thread in a new location */
755 _cygtls::interrupt_setup (int sig, void *handler, struct sigaction& siga)
757 push ((__stack_t) sigdelayed);
758 deltamask = siga.sa_mask & ~SIG_NONMASKABLE;
759 sa_flags = siga.sa_flags;
760 func = (void (*) (int)) handler;
761 if (siga.sa_flags & SA_RESETHAND)
762 siga.sa_handler = SIG_DFL;
763 saved_errno = -1; // Flag: no errno to save
764 if (handler == sig_handle_tty_stop)
767 myself->process_state |= PID_STOPPED;
770 this->sig = sig; // Should always be last thing set to avoid a race
781 /* Clear any waiting threads prior to dispatching to handler function */
782 int res = SetEvent (signal_arrived); // For an EINTR case
783 proc_subproc (PROC_CLEARWAIT, 1);
784 sigproc_printf ("armed signal_arrived %p, sig %d, res %d", signal_arrived,
788 extern "C" void __stdcall
789 set_sig_errno (int e)
791 *_my_tls.errno_addr = e;
792 _my_tls.saved_errno = e;
793 // sigproc_printf ("errno %d", e);
796 static int setup_handler (int, void *, struct sigaction&, _cygtls *tls)
797 __attribute__((regparm(3)));
799 setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls)
802 bool interrupted = false;
806 sigproc_printf ("trying to send sig %d but signal %d already armed",
811 for (int i = 0; i < CALL_HANDLER_RETRY; i++)
816 sigproc_printf ("controlled interrupt. stackptr %p, stack %p, stackptr[-1] %p",
817 tls->stackptr, tls->stack, tls->stackptr[-1]);
818 tls->interrupt_setup (sig, handler, siga);
826 HANDLE hth = (HANDLE) *tls;
828 /* Suspend the thread which will receive the signal.
829 For Windows 95, we also have to ensure that the addresses returned by
830 GetThreadContext are valid.
831 If one of these conditions is not true we loop for a fixed number of times
832 since we don't want to stall the signal handler. FIXME: Will this result in
834 If the thread is already suspended (which can occur when a program has called
835 SuspendThread on itself) then just queue the signal. */
838 sigproc_printf ("suspending mainthread");
840 cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
841 if (!GetThreadContext (hth, &cx))
842 memset (&cx, 0, sizeof cx);
843 sigproc_printf ("suspending mainthread PC %p", cx.Eip);
845 res = SuspendThread (hth);
846 /* Just set pending if thread is already suspended */
852 cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
853 if (!GetThreadContext (hth, &cx))
854 system_printf ("couldn't get context of main thread, %E");
856 interrupted = tls->interrupt_now (&cx, sig, handler, siga);
858 res = ResumeThread (hth);
862 sigproc_printf ("couldn't interrupt. trying again.");
863 low_priority_sleep (0);
867 sigproc_printf ("signal %d %sdelivered", sig, interrupted ? "" : "not ");
872 has_visible_window_station ()
878 /* Check if the process is associated with a visible window station.
879 These are processes running on the local desktop as well as processes
880 running in terminal server sessions.
881 Processes running in a service session not explicitely associated
882 with the desktop (using the "Allow service to interact with desktop"
883 property) are running in an invisible window station. */
884 if ((station_hdl = GetProcessWindowStation ())
885 && GetUserObjectInformationA (station_hdl, UOI_FLAGS, &uof,
887 && (uof.dwFlags & WSF_VISIBLE))
892 /* Keyboard interrupt handler. */
894 ctrl_c_handler (DWORD type)
896 static bool saw_close;
898 if (!cygwin_finished_initializing)
900 if (myself->cygstarted) /* Was this process created by a cygwin process? */
901 return TRUE; /* Yes. Let the parent eventually handle CTRL-C issues. */
902 debug_printf ("exiting with status %p", STATUS_CONTROL_C_EXIT);
903 ExitProcess (STATUS_CONTROL_C_EXIT);
906 _my_tls.remove (INFINITE);
909 if (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT)
910 proc_subproc (PROC_KILLFORKED, 0);
913 /* Return FALSE to prevent an "End task" dialog box from appearing
914 for each Cygwin process window that's open when the computer
915 is shut down or console window is closed. */
917 if (type == CTRL_SHUTDOWN_EVENT)
920 /* Don't send a signal. Only NT service applications and their child
921 processes will receive this event and the services typically already
922 handle the shutdown action when getting the SERVICE_CONTROL_SHUTDOWN
924 sig_send (NULL, SIGTERM);
929 if (myself->ctty != -1)
931 if (type == CTRL_CLOSE_EVENT)
933 sig_send (NULL, SIGHUP);
937 if (!saw_close && type == CTRL_LOGOFF_EVENT)
939 /* The CTRL_LOGOFF_EVENT is sent when *any* user logs off.
940 The below code sends a SIGHUP only if it is not performing the
941 default activity for SIGHUP. Note that it is possible for two
942 SIGHUP signals to arrive if a process group leader is exiting
943 too. Getting this 100% right is saved for a future cygwin mailing
945 if (global_sigs[SIGHUP].sa_handler != SIG_DFL)
947 sig_send (myself_nowait, SIGHUP);
956 chExeced->set_saw_ctrl_c ();
960 /* We're only the process group leader when we have a valid pinfo structure.
961 If we don't have one, then the parent "stub" will handle the signal. */
962 if (!pinfo (cygwin_pid (GetCurrentProcessId ())))
965 tty_min *t = cygwin_shared->tty.get_tty (myself->ctty);
966 /* Ignore this if we're not the process group leader since it should be handled
967 *by* the process group leader. */
968 if (myself->ctty != -1 && t->getpgid () == myself->pid &&
969 (GetTickCount () - t->last_ctrl_c) >= MIN_CTRL_C_SLOP)
970 /* Otherwise we just send a SIGINT to the process group and return TRUE (to indicate
971 that we have handled the signal). At this point, type should be
972 a CTRL_C_EVENT or CTRL_BREAK_EVENT. */
975 /* If intr and quit are both mapped to ^C, send SIGQUIT on ^BREAK */
976 if (type == CTRL_BREAK_EVENT
977 && t->ti.c_cc[VINTR] == 3 && t->ti.c_cc[VQUIT] == 3)
979 t->last_ctrl_c = GetTickCount ();
980 killsys (-myself->pid, sig);
981 t->last_ctrl_c = GetTickCount ();
988 /* Function used by low level sig wrappers. */
989 extern "C" void __stdcall
990 set_process_mask (sigset_t newmask)
992 set_signal_mask (newmask, myself->getsigmask ());
993 sigproc_printf ("mask now %p\n", myself->getsigmask ());
999 /* check that sig is in right range */
1000 if (sig < 0 || sig >= NSIG)
1003 syscall_printf ("signal %d out of range", sig);
1006 mask_sync.acquire (INFINITE);
1007 sigset_t mask = myself->getsigmask ();
1008 sigaddset (&mask, sig);
1009 set_signal_mask (mask, myself->getsigmask ());
1010 mask_sync.release ();
1017 /* check that sig is in right range */
1018 if (sig < 0 || sig >= NSIG)
1021 syscall_printf ("signal %d out of range", sig);
1024 mask_sync.acquire (INFINITE);
1025 sigset_t mask = myself->getsigmask ();
1026 sigdelset (&mask, sig);
1027 set_signal_mask (mask, myself->getsigmask ());
1028 mask_sync.release ();
1032 extern "C" _sig_func_ptr
1033 sigset (int sig, _sig_func_ptr func)
1035 sig_dispatch_pending ();
1038 /* check that sig is in right range */
1039 if (sig < 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
1042 syscall_printf ("SIG_ERR = sigset (%d, %p)", sig, func);
1043 return (_sig_func_ptr) SIG_ERR;
1046 mask_sync.acquire (INFINITE);
1047 sigset_t mask = myself->getsigmask ();
1048 /* If sig was in the signal mask return SIG_HOLD, otherwise return the
1049 previous disposition. */
1050 if (sigismember (&mask, sig))
1053 prev = global_sigs[sig].sa_handler;
1054 /* If func is SIG_HOLD, add sig to the signal mask, otherwise set the
1055 disposition to func and remove sig from the signal mask. */
1056 if (func == SIG_HOLD)
1057 sigaddset (&mask, sig);
1060 /* No error checking. The test which could return SIG_ERR has already
1063 sigdelset (&mask, sig);
1065 set_signal_mask (mask, myself->getsigmask ());
1066 mask_sync.release ();
1073 return sigset (sig, SIG_IGN) == SIG_ERR ? -1 : 0;
1076 /* Update the signal mask for this process and return the old mask.
1077 Called from sigdelayed */
1079 set_process_mask_delta ()
1081 mask_sync.acquire (INFINITE);
1082 sigset_t newmask, oldmask;
1084 if (_my_tls.deltamask & SIG_NONMASKABLE)
1085 oldmask = _my_tls.oldmask; /* from handle_sigsuspend */
1087 oldmask = myself->getsigmask ();
1088 newmask = (oldmask | _my_tls.deltamask) & ~SIG_NONMASKABLE;
1089 sigproc_printf ("oldmask %p, newmask %p, deltamask %p", oldmask, newmask,
1091 myself->setsigmask (newmask);
1092 mask_sync.release ();
1096 /* Set the signal mask for this process.
1097 Note that some signals are unmaskable, as in UNIX. */
1098 extern "C" void __stdcall
1099 set_signal_mask (sigset_t newmask, sigset_t& oldmask)
1102 if (&_my_tls == _sig_tls)
1103 small_printf ("********* waiting in signal thread\n");
1105 mask_sync.acquire (INFINITE);
1106 newmask &= ~SIG_NONMASKABLE;
1107 sigset_t mask_bits = oldmask & ~newmask;
1108 sigproc_printf ("oldmask %p, newmask %p, mask_bits %p", oldmask, newmask,
1112 sig_dispatch_pending (true);
1114 sigproc_printf ("not calling sig_dispatch_pending");
1115 mask_sync.release ();
1119 sigpacket::process ()
1122 struct sigaction dummy = global_sigs[SIGSTOP];
1124 if (si.si_signo != SIGCONT)
1125 continue_now = false;
1128 continue_now = myself->process_state & PID_STOPPED;
1129 myself->stopsig = 0;
1130 myself->process_state &= ~PID_STOPPED;
1131 /* Clear pending stop signals */
1132 sig_clear (SIGSTOP);
1133 sig_clear (SIGTSTP);
1134 sig_clear (SIGTTIN);
1135 sig_clear (SIGTTOU);
1140 sigproc_printf ("signal %d processing", si.si_signo);
1141 struct sigaction& thissig = global_sigs[si.si_signo];
1143 myself->rusage_self.ru_nsignals++;
1147 if (!hExeced || (void *) thissig.sa_handler == (void *) SIG_IGN)
1148 handler = (void *) thissig.sa_handler;
1154 if (si.si_signo == SIGKILL)
1156 if (si.si_signo == SIGSTOP)
1158 sig_clear (SIGCONT);
1164 bool insigwait_mask;
1165 if ((masked = ISSTATE (myself, PID_STOPPED)))
1166 insigwait_mask = false;
1168 insigwait_mask = !handler && (tls = _cygtls::find_tls (si.si_signo));
1170 insigwait_mask = sigismember (&tls->sigwait_mask, si.si_signo);
1173 goto thread_specific;
1176 /* nothing to do */;
1177 else if (sigismember (mask, si.si_signo))
1180 masked = sigismember (&tls->sigmask, si.si_signo);
1187 sigproc_printf ("signal %d blocked", si.si_signo);
1192 /* Clear pending SIGCONT on stop signals */
1193 if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
1194 sig_clear (SIGCONT);
1197 if (being_debugged ())
1199 char sigmsg[sizeof (_CYGWIN_SIGNAL_STRING " 0xffffffff")];
1200 __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %p", si.si_signo);
1201 OutputDebugString (sigmsg);
1205 if (handler == (void *) SIG_DFL)
1208 goto thread_specific;
1209 if (si.si_signo == SIGCHLD || si.si_signo == SIGIO || si.si_signo == SIGCONT || si.si_signo == SIGWINCH
1210 || si.si_signo == SIGURG)
1212 sigproc_printf ("default signal %d ignored", si.si_signo);
1214 SetEvent (signal_arrived);
1218 if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
1224 if (handler == (void *) SIG_IGN)
1226 sigproc_printf ("signal %d ignored", si.si_signo);
1230 if (handler == (void *) SIG_ERR)
1233 tls->set_siginfo (this);
1237 /* Eat multiple attempts to STOP */
1238 if (ISSTATE (myself, PID_STOPPED))
1240 handler = (void *) sig_handle_tty_stop;
1244 /* Dispatch to the appropriate function. */
1245 sigproc_printf ("signal %d, about to call %p", si.si_signo, handler);
1246 rc = setup_handler (si.si_signo, handler, thissig, tls);
1251 sigproc_printf ("returning %d", rc);
1255 tls->sig = si.si_signo;
1256 tls->set_siginfo (this);
1257 sigproc_printf ("releasing sigwait for thread");
1258 SetEvent (tls->event);
1262 if (si.si_signo == SIGQUIT || si.si_signo == SIGABRT)
1265 c.ContextFlags = CONTEXT_FULL;
1266 GetThreadContext (hMainThread, &c);
1267 tls->copy_context (&c);
1268 si.si_signo |= 0x80;
1270 sigproc_printf ("signal %d, about to call do_exit", si.si_signo);
1271 tls->signal_exit (si.si_signo); /* never returns */
1274 /* Cover function to `do_exit' to handle exiting even in presence of more
1275 exceptions. We used to call exit, but a SIGSEGV shouldn't cause atexit
1278 _cygtls::signal_exit (int rc)
1282 sigproc_printf ("terminating captive process");
1283 TerminateProcess (hExeced, sigExeced = rc);
1286 signal_debugger (rc & 0x7f);
1287 if ((rc & 0x80) && !try_to_debug ())
1288 stackdump (thread_context.ebp, 1, 1);
1290 lock_process until_exit (true);
1291 if (hExeced || exit_state)
1294 /* Starve other threads in a vain attempt to stop them from doing something
1296 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
1298 user_data->resourcelocks->Delete ();
1299 user_data->resourcelocks->Init ();
1301 sigproc_printf ("about to call do_exit (%x)", rc);
1302 SetEvent (signal_arrived);
1309 mask_sync.init ("mask_sync");
1310 windows_system_directory[0] = '\0';
1311 GetSystemDirectory (windows_system_directory, sizeof (windows_system_directory) - 2);
1312 char *end = strchr (windows_system_directory, '\0');
1313 if (end == windows_system_directory)
1314 api_fatal ("can't find windows system directory");
1315 if (end[-1] != '\\')
1320 windows_system_directory_length = end - windows_system_directory;
1321 debug_printf ("windows_system_directory '%s', windows_system_directory_length %d",
1322 windows_system_directory, windows_system_directory_length);
1332 _cygtls::call_signal_handler ()
1334 int this_sa_flags = 0;
1335 /* Call signal handler. */
1339 this_sa_flags = sa_flags;
1343 reset_signal_arrived ();
1344 sigset_t this_oldmask = set_process_mask_delta ();
1345 int this_errno = saved_errno;
1347 unlock (); // make sure synchronized
1349 if (!(this_sa_flags & SA_SIGINFO))
1351 void (*sigfunc) (int) = func;
1356 siginfo_t thissi = infodata;
1357 void (*sigact) (int, siginfo_t *, void *) = (void (*) (int, siginfo_t *, void *)) func;
1358 /* no ucontext_t information provided yet */
1359 sigact (thissig, &thissi, NULL);
1362 set_signal_mask (this_oldmask, myself->getsigmask ());
1363 if (this_errno >= 0)
1364 set_errno (this_errno);
1367 return this_sa_flags & SA_RESTART;
1370 extern "C" void __stdcall
1371 reset_signal_arrived ()
1373 // NEEDED? WaitForSingleObject (signal_arrived, 10);
1374 ResetEvent (signal_arrived);
1375 sigproc_printf ("reset signal_arrived");
1376 if (_my_tls.stackptr > _my_tls.stack)
1377 debug_printf ("stackptr[-1] %p", _my_tls.stackptr[-1]);
1381 _cygtls::copy_context (CONTEXT *c)
1383 memcpy (&thread_context, c, (&thread_context._internal - (unsigned char *) &thread_context));
1387 _cygtls::signal_debugger (int sig)
1389 if (isinitialized () && being_debugged ())
1391 char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING " ffffffff ffffffff")];
1392 __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %d %p %p", sig, thread_id, &thread_context);
1393 OutputDebugString (sigmsg);