3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007, 2008, 2009, 2010, 2011 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
14 #include "miscfuncs.h"
25 #include "shared_info.h"
26 #include "perprocess.h"
31 #include "child_info.h"
33 #include "exception.h"
35 #define CALL_HANDLER_RETRY_OUTER 10
36 #define CALL_HANDLER_RETRY_INNER 10
38 char debugger_command[2 * NT_MAX_PATH + 20];
41 extern void sigdelayed ();
44 static BOOL WINAPI ctrl_c_handler (DWORD);
46 /* This is set to indicate that we have already exited. */
48 static NO_COPY int exit_already = 0;
49 static muto NO_COPY mask_sync;
58 { X (STATUS_ABANDONED_WAIT_0) },
59 { X (STATUS_ACCESS_VIOLATION) },
60 { X (STATUS_ARRAY_BOUNDS_EXCEEDED) },
61 { X (STATUS_BREAKPOINT) },
62 { X (STATUS_CONTROL_C_EXIT) },
63 { X (STATUS_DATATYPE_MISALIGNMENT) },
64 { X (STATUS_FLOAT_DENORMAL_OPERAND) },
65 { X (STATUS_FLOAT_DIVIDE_BY_ZERO) },
66 { X (STATUS_FLOAT_INEXACT_RESULT) },
67 { X (STATUS_FLOAT_INVALID_OPERATION) },
68 { X (STATUS_FLOAT_OVERFLOW) },
69 { X (STATUS_FLOAT_STACK_CHECK) },
70 { X (STATUS_FLOAT_UNDERFLOW) },
71 { X (STATUS_GUARD_PAGE_VIOLATION) },
72 { X (STATUS_ILLEGAL_INSTRUCTION) },
73 { X (STATUS_INTEGER_DIVIDE_BY_ZERO) },
74 { X (STATUS_INTEGER_OVERFLOW) },
75 { X (STATUS_INVALID_DISPOSITION) },
76 { X (STATUS_IN_PAGE_ERROR) },
77 { X (STATUS_NONCONTINUABLE_EXCEPTION) },
78 { X (STATUS_NO_MEMORY) },
79 { X (STATUS_PENDING) },
80 { X (STATUS_PRIVILEGED_INSTRUCTION) },
81 { X (STATUS_SINGLE_STEP) },
82 { X (STATUS_STACK_OVERFLOW) },
83 { X (STATUS_TIMEOUT) },
84 { X (STATUS_USER_APC) },
85 { X (STATUS_WAIT_0) },
90 /* Initialization code. */
93 init_console_handler (bool install_handler)
97 SetConsoleCtrlHandler (ctrl_c_handler, FALSE);
98 SetConsoleCtrlHandler (NULL, FALSE);
100 res = SetConsoleCtrlHandler (ctrl_c_handler, TRUE);
102 res = SetConsoleCtrlHandler (NULL, TRUE);
104 system_printf ("SetConsoleCtrlHandler failed, %E");
108 error_start_init (const char *buf)
112 debugger_command[0] = '\0';
116 char pgm[NT_MAX_PATH];
117 if (!GetModuleFileName (NULL, pgm, NT_MAX_PATH))
118 strcpy (pgm, "cygwin1.dll");
119 for (char *p = strchr (pgm, '\\'); p; p = strchr (p, '\\'))
122 __small_sprintf (debugger_command, "%s \"%s\"", buf, pgm);
126 open_stackdumpfile ()
128 /* If we have no executable name, or if the CWD handle is NULL,
129 which means, the CWD is a virtual path, don't even try to open
131 if (myself->progname[0] && cygheap->cwd.get_handle ())
134 /* write to progname.stackdump if possible */
135 if (!myself->progname[0])
137 else if ((p = wcsrchr (myself->progname, L'\\')))
140 p = myself->progname;
142 WCHAR corefile[wcslen (p) + sizeof (".stackdump")];
143 wcpcpy (wcpcpy(corefile, p), L".stackdump");
144 UNICODE_STRING ucore;
145 OBJECT_ATTRIBUTES attr;
146 /* Create the UNICODE variation of <progname>.stackdump. */
147 RtlInitUnicodeString (&ucore, corefile);
148 /* Create an object attribute which refers to <progname>.stackdump
149 in Cygwin's cwd. Stick to caseinsensitivity. */
150 InitializeObjectAttributes (&attr, &ucore, OBJ_CASE_INSENSITIVE,
151 cygheap->cwd.get_handle (), NULL);
155 /* Try to open it to dump the stack in it. */
156 status = NtCreateFile (&h, GENERIC_WRITE | SYNCHRONIZE, &attr, &io,
157 NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
158 FILE_SYNCHRONOUS_IO_NONALERT
159 | FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0);
160 if (NT_SUCCESS (status))
162 if (!myself->cygstarted)
163 system_printf ("Dumping stack trace to %S", &ucore);
165 debug_printf ("Dumping stack trace to %S", &ucore);
166 SetStdHandle (STD_ERROR_HANDLE, h);
171 /* Utilities for dumping the stack, etc. */
174 dump_exception (EXCEPTION_RECORD *e, CONTEXT *in)
176 const char *exception_name = NULL;
180 for (int i = 0; status_info[i].name; i++)
182 if (status_info[i].code == e->ExceptionCode)
184 exception_name = status_info[i].name;
191 small_printf ("Exception: %s at eip=%08x\r\n", exception_name, in->Eip);
193 small_printf ("Signal %d at eip=%08x\r\n", e->ExceptionCode, in->Eip);
194 small_printf ("eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\r\n",
195 in->Eax, in->Ebx, in->Ecx, in->Edx, in->Esi, in->Edi);
196 small_printf ("ebp=%08x esp=%08x program=%W, pid %u, thread %s\r\n",
197 in->Ebp, in->Esp, myself->progname, myself->pid, cygthread::name ());
198 small_printf ("cs=%04x ds=%04x es=%04x fs=%04x gs=%04x ss=%04x\r\n",
199 in->SegCs, in->SegDs, in->SegEs, in->SegFs, in->SegGs, in->SegSs);
202 /* A class for manipulating the stack. */
205 int walk (); /* Uses the "old" method */
206 char *next_offset () {return *((char **) sf.AddrFrame.Offset);}
210 STACKFRAME sf; /* For storing the stack information */
211 void init (DWORD, bool, bool); /* Called the first time that stack info is needed */
213 /* Postfix ++ iterates over the stack, returning zero when nothing is left. */
214 int operator ++(int) { return walk (); }
217 /* The number of parameters used in STACKFRAME */
218 #define NPARAMS (sizeof (thestack.sf.Params) / sizeof (thestack.sf.Params[0]))
220 /* This is the main stack frame info for this process. */
221 static NO_COPY stack_info thestack;
223 /* Initialize everything needed to start iterating. */
225 stack_info::init (DWORD ebp, bool wantargs, bool goodframe)
227 # define debp ((DWORD *) ebp)
228 memset (&sf, 0, sizeof (sf));
230 sf.AddrFrame.Offset = ebp;
234 sf.AddrFrame.Offset = (DWORD) &dummy_frame;
236 sf.AddrReturn.Offset = debp[1];
237 sf.AddrFrame.Mode = AddrModeFlat;
242 extern "C" void _cygwin_exit_return ();
244 /* Walk the stack by looking at successive stored 'bp' frames.
245 This is not foolproof. */
251 if ((void (*) ()) sf.AddrPC.Offset == _cygwin_exit_return)
252 return 0; /* stack frames are exhausted */
254 if (((ebp = (char **) next_offset ()) == NULL) || (ebp >= (char **) cygwin_hmodule))
257 sf.AddrFrame.Offset = (DWORD) ebp;
258 sf.AddrPC.Offset = sf.AddrReturn.Offset;
260 /* The return address always follows the stack pointer */
261 sf.AddrReturn.Offset = (DWORD) *++ebp;
265 unsigned nparams = NPARAMS;
267 /* The arguments follow the return address */
268 sf.Params[0] = (DWORD) *++ebp;
269 /* Hack for XP/2K3 WOW64. If the first stack param points to the
270 application entry point, we can only fetch one additional
271 parameter. Accessing anything beyond this address results in
272 a SEGV. This is fixed in Vista/2K8 WOW64. */
273 if (wincap.has_restricted_stack_args () && sf.Params[0] == 0x401000)
275 for (unsigned i = 1; i < nparams; i++)
276 sf.Params[i] = (DWORD) *++ebp;
283 stackdump (DWORD ebp, int open_file, bool isexception)
285 static bool already_dumped;
287 if (cygheap->rlim_core == 0UL || (open_file && already_dumped))
291 open_stackdumpfile ();
293 already_dumped = true;
297 thestack.init (ebp, 1, !isexception); /* Initialize from the input CONTEXT */
298 small_printf ("Stack trace:\r\nFrame Function Args\r\n");
299 for (i = 0; i < 16 && thestack++; i++)
301 small_printf ("%08x %08x ", thestack.sf.AddrFrame.Offset,
302 thestack.sf.AddrPC.Offset);
303 for (unsigned j = 0; j < NPARAMS; j++)
304 small_printf ("%s%08x", j == 0 ? " (" : ", ", thestack.sf.Params[j]);
305 small_printf (")\r\n");
307 small_printf ("End of stack trace%s\n",
308 i == 16 ? " (more stack frames may be present)" : "");
312 _cygtls::inside_kernel (CONTEXT *cx)
315 MEMORY_BASIC_INFORMATION m;
317 if (!isinitialized ())
320 memset (&m, 0, sizeof m);
321 if (!VirtualQuery ((LPCVOID) cx->Eip, &m, sizeof m))
322 sigproc_printf ("couldn't get memory info, pc %p, %E", cx->Eip);
324 size_t size = (windows_system_directory_length + 6) * sizeof (WCHAR);
325 PWCHAR checkdir = (PWCHAR) alloca (size);
326 memset (checkdir, 0, size);
328 # define h ((HMODULE) m.AllocationBase)
329 /* Apparently Windows 95 can sometimes return bogus addresses from
330 GetThreadContext. These resolve to a strange allocation base.
331 These should *never* be treated as interruptible. */
332 if (!h || m.State != MEM_COMMIT)
334 else if (h == user_data->hmodule)
336 else if (!GetModuleFileNameW (h, checkdir, windows_system_directory_length + 6))
340 /* Skip potential long path prefix. */
341 if (!wcsncmp (checkdir, L"\\\\?\\", 4))
343 res = !wcsncasecmp (windows_system_directory, checkdir,
344 windows_system_directory_length);
346 sigproc_printf ("pc %p, h %p, inside_kernel %d", cx->Eip, h, res);
351 /* Temporary (?) function for external callers to get a stack dump */
356 c.ContextFlags = CONTEXT_FULL;
357 GetThreadContext (GetCurrentThread (), &c);
358 stackdump (c.Ebp, 0, 0);
361 #define TIME_TO_WAIT_FOR_DEBUGGER 10000
364 try_to_debug (bool waitloop)
366 debug_printf ("debugger_command '%s'", debugger_command);
367 if (*debugger_command == '\0')
369 if (being_debugged ())
371 extern void break_here ();
376 __small_sprintf (strchr (debugger_command, '\0'), " %u", GetCurrentProcessId ());
378 LONG prio = GetThreadPriority (GetCurrentThread ());
379 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
380 PROCESS_INFORMATION pi = {NULL, 0, 0, 0};
382 STARTUPINFOW si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
383 si.lpReserved = NULL;
388 /* FIXME: need to know handles of all running threads to
389 suspend_all_threads_except (current_thread_id);
392 /* If the tty mutex is owned, we will fail to start any cygwin app
393 until the trapped app exits. However, this will only release any
394 the mutex if it is owned by this thread so that may be problematic. */
396 lock_ttys::release ();
398 /* prevent recursive exception handling */
399 PWCHAR rawenv = GetEnvironmentStringsW () ;
400 for (PWCHAR p = rawenv; *p != L'\0'; p = wcschr (p, L'\0') + 1)
402 if (wcsncmp (p, L"CYGWIN=", wcslen (L"CYGWIN=")) == 0)
404 PWCHAR q = wcsstr (p, L"error_start") ;
405 /* replace 'error_start=...' with '_rror_start=...' */
409 SetEnvironmentVariableW (L"CYGWIN", p + wcslen (L"CYGWIN=")) ;
415 console_printf ("*** starting debugger for pid %u, tid %u\n",
416 cygwin_pid (GetCurrentProcessId ()), GetCurrentThreadId ());
418 WCHAR dbg_cmd[strlen(debugger_command)];
419 sys_mbstowcs (dbg_cmd, strlen(debugger_command) + 1, debugger_command);
420 dbg = CreateProcessW (NULL,
425 CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,
432 system_printf ("Failed to start debugger, %E");
437 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_IDLE);
438 while (!being_debugged ())
443 console_printf ("*** continuing pid %u from debugger call (%d)\n",
444 cygwin_pid (GetCurrentProcessId ()), dbg);
446 SetThreadPriority (GetCurrentThread (), prio);
450 extern "C" DWORD __stdcall RtlUnwind (void *, void *, void *, DWORD);
451 static void __stdcall rtl_unwind (exception_list *, PEXCEPTION_RECORD) __attribute__ ((noinline, regparm (3)));
453 rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
463 call _RtlUnwind@16 \n\
468 ": : "r" (frame), "r" (e));
471 /* Main exception handler. */
473 extern exception_list *_except_list asm ("%fs:0");
476 exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void *)
478 static bool NO_COPY debugging;
479 static int NO_COPY recursed;
480 _cygtls& me = _my_tls;
482 if (debugging && ++debugging < 500000)
484 SetThreadPriority (hMainThread, THREAD_PRIORITY_NORMAL);
488 /* If we've already exited, don't do anything here. Returning 1
489 tells Windows to keep looking for an exception handler. */
490 if (exit_already || e->ExceptionFlags)
494 si.si_code = SI_KERNEL;
495 /* Coerce win32 value to posix value. */
496 switch (e->ExceptionCode)
498 case STATUS_FLOAT_DENORMAL_OPERAND:
499 case STATUS_FLOAT_DIVIDE_BY_ZERO:
500 case STATUS_FLOAT_INVALID_OPERATION:
501 case STATUS_FLOAT_STACK_CHECK:
502 si.si_signo = SIGFPE;
503 si.si_code = FPE_FLTSUB;
505 case STATUS_FLOAT_INEXACT_RESULT:
506 si.si_signo = SIGFPE;
507 si.si_code = FPE_FLTRES;
509 case STATUS_FLOAT_OVERFLOW:
510 si.si_signo = SIGFPE;
511 si.si_code = FPE_FLTOVF;
513 case STATUS_FLOAT_UNDERFLOW:
514 si.si_signo = SIGFPE;
515 si.si_code = FPE_FLTUND;
517 case STATUS_INTEGER_DIVIDE_BY_ZERO:
518 si.si_signo = SIGFPE;
519 si.si_code = FPE_INTDIV;
521 case STATUS_INTEGER_OVERFLOW:
522 si.si_signo = SIGFPE;
523 si.si_code = FPE_INTOVF;
526 case STATUS_ILLEGAL_INSTRUCTION:
527 si.si_signo = SIGILL;
528 si.si_code = ILL_ILLOPC;
531 case STATUS_PRIVILEGED_INSTRUCTION:
532 si.si_signo = SIGILL;
533 si.si_code = ILL_PRVOPC;
536 case STATUS_NONCONTINUABLE_EXCEPTION:
537 si.si_signo = SIGILL;
538 si.si_code = ILL_ILLADR;
542 si.si_signo = SIGALRM;
545 case STATUS_GUARD_PAGE_VIOLATION:
546 si.si_signo = SIGBUS;
547 si.si_code = BUS_OBJERR;
550 case STATUS_DATATYPE_MISALIGNMENT:
551 si.si_signo = SIGBUS;
552 si.si_code = BUS_ADRALN;
555 case STATUS_ACCESS_VIOLATION:
556 switch (mmap_is_attached_or_noreserve ((void *)e->ExceptionInformation[1],
559 case MMAP_NORESERVE_COMMITED:
561 case MMAP_RAISE_SIGBUS: /* MAP_NORESERVE page, commit failed, or
562 access to mmap page beyond EOF. */
563 si.si_signo = SIGBUS;
564 si.si_code = BUS_OBJERR;
567 MEMORY_BASIC_INFORMATION m;
568 VirtualQuery ((PVOID) e->ExceptionInformation[1], &m, sizeof m);
569 si.si_signo = SIGSEGV;
570 si.si_code = m.State == MEM_FREE ? SEGV_MAPERR : SEGV_ACCERR;
575 case STATUS_ARRAY_BOUNDS_EXCEEDED:
576 case STATUS_IN_PAGE_ERROR:
577 case STATUS_NO_MEMORY:
578 case STATUS_INVALID_DISPOSITION:
579 case STATUS_STACK_OVERFLOW:
580 si.si_signo = SIGSEGV;
581 si.si_code = SEGV_MAPERR;
584 case STATUS_CONTROL_C_EXIT:
585 si.si_signo = SIGINT;
588 case STATUS_INVALID_HANDLE:
589 /* CloseHandle will throw this exception if it is given an
590 invalid handle. We don't care about the exception; we just
591 want CloseHandle to return an error. This can be revisited
592 if gcc ever supports Windows style structured exception
597 /* If we don't recognize the exception, we have to assume that
598 we are doing structured exception handling, and we let
599 something else handle it. */
603 debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp);
604 debug_printf ("In cygwin_except_handler signal %d at %p", si.si_signo, in->Eip);
606 bool masked = !!(me.sigmask & SIGTOMASK (si.si_signo));
608 syscall_printf ("signal %d, masked %p", si.si_signo,
609 global_sigs[si.si_signo].sa_mask);
611 debug_printf ("In cygwin_except_handler calling %p",
612 global_sigs[si.si_signo].sa_handler);
614 DWORD *ebp = (DWORD *) in->Esp;
615 for (DWORD *bpend = (DWORD *) __builtin_frame_address (0); ebp > bpend; ebp--)
616 if (*ebp == in->SegCs && ebp[-1] == in->Eip)
623 me.andreas->leave (); /* Return from a "san" caught fault */
625 me.copy_context (in);
627 /* Temporarily replace windows top level SEH with our own handler.
628 We don't want any Windows magic kicking in. This top level frame
629 will be removed automatically after our exception handler returns. */
630 _except_list->handler = handle;
634 || !cygwin_finished_initializing
635 || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL
636 || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN
637 || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR)
639 /* Print the exception to the console */
640 if (!myself->cygstarted)
641 for (int i = 0; status_info[i].name; i++)
642 if (status_info[i].code == e->ExceptionCode)
644 system_printf ("Exception: %s", status_info[i].name);
648 /* Another exception could happen while tracing or while exiting.
649 Only do this once. */
651 system_printf ("Error while dumping state (probably corrupted stack)");
654 if (try_to_debug (0))
660 rtl_unwind (frame, e);
661 if (cygheap->rlim_core > 0UL)
663 open_stackdumpfile ();
664 dump_exception (e, in);
665 stackdump ((DWORD) ebp, 0, 1);
669 if (e->ExceptionCode == STATUS_ACCESS_VIOLATION)
672 if (si.si_code == SEGV_ACCERR) /* Address present */
674 if (e->ExceptionInformation[0]) /* Write access */
676 if (!me.inside_kernel (in)) /* User space */
678 klog (LOG_INFO, "%s[%d]: segfault at %08x rip %08x rsp %08x error %d",
679 __progname, myself->pid,
680 e->ExceptionInformation[1], in->Eip, in->Esp,
681 ((in->Eip >= 0x61000000 && in->Eip < 0x61200000)
682 ? 0 : 4) | (e->ExceptionInformation[0] << 1));
685 /* Flag signal + core dump */
686 me.signal_exit ((cygheap->rlim_core > 0UL ? 0x80 : 0) | si.si_signo);
689 si.si_addr = (si.si_signo == SIGSEGV || si.si_signo == SIGBUS
690 ? (void *) e->ExceptionInformation[1]
692 si.si_errno = si.si_pid = si.si_uid = 0;
694 sig_send (NULL, si, &me); // Signal myself
696 e->ExceptionFlags = 0;
700 /* Utilities to call a user supplied exception handler. */
702 #define SIG_NONMASKABLE (SIGTOMASK (SIGKILL) | SIGTOMASK (SIGSTOP))
704 /* Non-raceable sigsuspend
705 * Note: This implementation is based on the Single UNIX Specification
706 * man page. This indicates that sigsuspend always returns -1 and that
707 * attempts to block unblockable signals will be silently ignored.
708 * This is counter to what appears to be documented in some UNIX
709 * man pages, e.g. Linux.
712 handle_sigsuspend (sigset_t tempmask)
714 sigset_t oldmask = _my_tls.sigmask; // Remember for restoration
716 set_signal_mask (tempmask, _my_tls.sigmask);
717 sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
719 pthread_testcancel ();
720 cancelable_wait (signal_arrived);
722 set_sig_errno (EINTR); // Per POSIX
724 /* A signal dispatch function will have been added to our stack and will
725 be hit eventually. Set the old mask to be restored when the signal
726 handler returns and indicate its presence by modifying deltamask. */
728 _my_tls.deltamask |= SIG_NONMASKABLE;
729 _my_tls.oldmask = oldmask; // Will be restored by signal handler
733 extern DWORD exec_exit; // Possible exit value for exec
737 sig_handle_tty_stop (int sig)
740 /* Silently ignore attempts to suspend if there is no accommodating
741 cygwin parent to deal with this behavior. */
742 if (!myself->cygstarted)
744 myself->process_state &= ~PID_STOPPED;
748 myself->stopsig = sig;
749 myself->alert_parent (sig);
750 sigproc_printf ("process %d stopped by signal %d", myself->pid, sig);
753 w4[1] = signal_arrived;
754 switch (WaitForMultipleObjects (2, w4, TRUE, INFINITE))
757 case WAIT_OBJECT_0 + 1:
758 reset_signal_arrived ();
759 myself->stopsig = SIGCONT;
760 myself->alert_parent (SIGCONT);
763 api_fatal ("WaitSingleObject failed, %E");
771 _cygtls::interrupt_now (CONTEXT *cx, int sig, void *handler,
772 struct sigaction& siga)
776 /* Delay the interrupt if we are
777 1) somehow inside the DLL
778 2) in _sigfe (spinning is true) and about to enter cygwin DLL
779 3) in a Windows DLL. */
780 if (incyg || spinning || inside_kernel (cx))
784 push ((__stack_t) cx->Eip);
785 interrupt_setup (sig, handler, siga);
787 SetThreadContext (*this, cx); /* Restart the thread in a new location */
794 _cygtls::interrupt_setup (int sig, void *handler, struct sigaction& siga)
796 push ((__stack_t) sigdelayed);
797 deltamask = siga.sa_mask & ~SIG_NONMASKABLE;
798 sa_flags = siga.sa_flags;
799 func = (void (*) (int)) handler;
800 if (siga.sa_flags & SA_RESETHAND)
801 siga.sa_handler = SIG_DFL;
802 saved_errno = -1; // Flag: no errno to save
803 if (handler == sig_handle_tty_stop)
806 myself->process_state |= PID_STOPPED;
809 this->sig = sig; // Should always be last thing set to avoid a race
820 /* Clear any waiting threads prior to dispatching to handler function */
821 int res = SetEvent (signal_arrived); // For an EINTR case
822 proc_subproc (PROC_CLEARWAIT, 1);
823 sigproc_printf ("armed signal_arrived %p, signal %d, res %d", signal_arrived,
827 extern "C" void __stdcall
828 set_sig_errno (int e)
830 *_my_tls.errno_addr = e;
831 _my_tls.saved_errno = e;
832 // sigproc_printf ("errno %d", e);
835 static int setup_handler (int, void *, struct sigaction&, _cygtls *tls)
836 __attribute__((regparm(3)));
838 setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls)
841 bool interrupted = false;
845 sigproc_printf ("trying to send signal %d but signal %d already armed",
850 for (int n = 0; n < CALL_HANDLER_RETRY_OUTER; n++)
852 for (int i = 0; i < CALL_HANDLER_RETRY_INNER; i++)
857 sigproc_printf ("controlled interrupt. stackptr %p, stack %p, stackptr[-1] %p",
858 tls->stackptr, tls->stack, tls->stackptr[-1]);
859 tls->interrupt_setup (sig, handler, siga);
866 HANDLE hth = (HANDLE) *tls;
868 /* Suspend the thread which will receive the signal.
869 If one of these conditions is not true we loop.
870 If the thread is already suspended (which can occur when a program
871 has called SuspendThread on itself) then just queue the signal. */
873 sigproc_printf ("suspending thread");
874 res = SuspendThread (hth);
875 /* Just set pending if thread is already suspended */
881 cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
882 if (!GetThreadContext (hth, &cx))
883 system_printf ("couldn't get context of thread, %E");
885 interrupted = tls->interrupt_now (&cx, sig, handler, siga);
888 res = ResumeThread (hth);
892 sigproc_printf ("couldn't interrupt. trying again.");
895 /* Hit here if we couldn't deliver the signal. Take a more drastic
896 action before trying again. */
901 sigproc_printf ("signal %d %sdelivered", sig, interrupted ? "" : "not ");
906 has_visible_window_station ()
912 /* Check if the process is associated with a visible window station.
913 These are processes running on the local desktop as well as processes
914 running in terminal server sessions.
915 Processes running in a service session not explicitely associated
916 with the desktop (using the "Allow service to interact with desktop"
917 property) are running in an invisible window station. */
918 if ((station_hdl = GetProcessWindowStation ())
919 && GetUserObjectInformationW (station_hdl, UOI_FLAGS, &uof,
921 && (uof.dwFlags & WSF_VISIBLE))
926 /* Keyboard interrupt handler. */
928 ctrl_c_handler (DWORD type)
930 static bool saw_close;
933 if (!cygwin_finished_initializing)
935 if (myself->cygstarted) /* Was this process created by a cygwin process? */
936 return TRUE; /* Yes. Let the parent eventually handle CTRL-C issues. */
937 debug_printf ("exiting with status %p", STATUS_CONTROL_C_EXIT);
938 ExitProcess (STATUS_CONTROL_C_EXIT);
941 _my_tls.remove (INFINITE);
944 if (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT)
945 proc_subproc (PROC_KILLFORKED, 0);
948 /* Return FALSE to prevent an "End task" dialog box from appearing
949 for each Cygwin process window that's open when the computer
950 is shut down or console window is closed. */
952 if (type == CTRL_SHUTDOWN_EVENT)
955 /* Don't send a signal. Only NT service applications and their child
956 processes will receive this event and the services typically already
957 handle the shutdown action when getting the SERVICE_CONTROL_SHUTDOWN
959 sig_send (NULL, SIGTERM);
964 if (myself->ctty != -1)
966 if (type == CTRL_CLOSE_EVENT)
968 sig_send (NULL, SIGHUP);
972 if (!saw_close && type == CTRL_LOGOFF_EVENT)
974 /* The CTRL_LOGOFF_EVENT is sent when *any* user logs off.
975 The below code sends a SIGHUP only if it is not performing the
976 default activity for SIGHUP. Note that it is possible for two
977 SIGHUP signals to arrive if a process group leader is exiting
978 too. Getting this 100% right is saved for a future cygwin mailing
980 if (global_sigs[SIGHUP].sa_handler != SIG_DFL)
982 sig_send (myself_nowait, SIGHUP);
989 if (ch_spawn.set_saw_ctrl_c ())
992 /* We're only the process group leader when we have a valid pinfo structure.
993 If we don't have one, then the parent "stub" will handle the signal. */
994 if (!pinfo (cygwin_pid (GetCurrentProcessId ())))
997 tty_min *t = cygwin_shared->tty.get_cttyp ();
998 /* Ignore this if we're not the process group leader since it should be handled
999 *by* the process group leader. */
1000 if (t && t->getpgid () == myself->pid &&
1001 (GetTickCount () - t->last_ctrl_c) >= MIN_CTRL_C_SLOP)
1002 /* Otherwise we just send a SIGINT to the process group and return TRUE (to indicate
1003 that we have handled the signal). At this point, type should be
1004 a CTRL_C_EVENT or CTRL_BREAK_EVENT. */
1007 /* If intr and quit are both mapped to ^C, send SIGQUIT on ^BREAK */
1008 if (type == CTRL_BREAK_EVENT
1009 && t->ti.c_cc[VINTR] == 3 && t->ti.c_cc[VQUIT] == 3)
1011 t->last_ctrl_c = GetTickCount ();
1012 killsys (-myself->pid, sig);
1013 t->last_ctrl_c = GetTickCount ();
1020 /* Function used by low level sig wrappers. */
1021 extern "C" void __stdcall
1022 set_process_mask (sigset_t newmask)
1024 set_signal_mask (newmask, _my_tls.sigmask);
1030 /* check that sig is in right range */
1031 if (sig < 0 || sig >= NSIG)
1034 syscall_printf ("signal %d out of range", sig);
1037 mask_sync.acquire (INFINITE);
1038 sigset_t mask = _my_tls.sigmask;
1039 sigaddset (&mask, sig);
1040 set_signal_mask (mask, _my_tls.sigmask);
1041 mask_sync.release ();
1048 /* check that sig is in right range */
1049 if (sig < 0 || sig >= NSIG)
1052 syscall_printf ("signal %d out of range", sig);
1055 mask_sync.acquire (INFINITE);
1056 sigset_t mask = _my_tls.sigmask;
1057 sigdelset (&mask, sig);
1058 set_signal_mask (mask, _my_tls.sigmask);
1059 mask_sync.release ();
1063 extern "C" _sig_func_ptr
1064 sigset (int sig, _sig_func_ptr func)
1066 sig_dispatch_pending ();
1069 /* check that sig is in right range */
1070 if (sig < 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
1073 syscall_printf ("SIG_ERR = sigset (%d, %p)", sig, func);
1074 return (_sig_func_ptr) SIG_ERR;
1077 mask_sync.acquire (INFINITE);
1078 sigset_t mask = _my_tls.sigmask;
1079 /* If sig was in the signal mask return SIG_HOLD, otherwise return the
1080 previous disposition. */
1081 if (sigismember (&mask, sig))
1084 prev = global_sigs[sig].sa_handler;
1085 /* If func is SIG_HOLD, add sig to the signal mask, otherwise set the
1086 disposition to func and remove sig from the signal mask. */
1087 if (func == SIG_HOLD)
1088 sigaddset (&mask, sig);
1091 /* No error checking. The test which could return SIG_ERR has already
1094 sigdelset (&mask, sig);
1096 set_signal_mask (mask, _my_tls.sigmask);
1097 mask_sync.release ();
1104 return sigset (sig, SIG_IGN) == SIG_ERR ? -1 : 0;
1107 /* Update the signal mask for this process and return the old mask.
1108 Called from sigdelayed */
1110 set_process_mask_delta ()
1112 mask_sync.acquire (INFINITE);
1113 sigset_t newmask, oldmask;
1115 if (_my_tls.deltamask & SIG_NONMASKABLE)
1116 oldmask = _my_tls.oldmask; /* from handle_sigsuspend */
1118 oldmask = _my_tls.sigmask;
1119 newmask = (oldmask | _my_tls.deltamask) & ~SIG_NONMASKABLE;
1120 sigproc_printf ("oldmask %p, newmask %p, deltamask %p", oldmask, newmask,
1122 _my_tls.sigmask = newmask;
1123 mask_sync.release ();
1127 /* Set the signal mask for this process.
1128 Note that some signals are unmaskable, as in UNIX. */
1129 extern "C" void __stdcall
1130 set_signal_mask (sigset_t newmask, sigset_t& oldmask)
1133 if (&_my_tls == _sig_tls)
1134 small_printf ("********* waiting in signal thread\n");
1136 mask_sync.acquire (INFINITE);
1137 newmask &= ~SIG_NONMASKABLE;
1138 sigset_t mask_bits = oldmask & ~newmask;
1139 sigproc_printf ("oldmask %p, newmask %p, mask_bits %p", oldmask, newmask,
1143 sig_dispatch_pending (true);
1145 sigproc_printf ("not calling sig_dispatch_pending");
1146 mask_sync.release ();
1150 sigpacket::process ()
1153 struct sigaction dummy = global_sigs[SIGSTOP];
1155 if (si.si_signo != SIGCONT)
1156 continue_now = false;
1159 continue_now = myself->process_state & PID_STOPPED;
1160 myself->stopsig = 0;
1161 myself->process_state &= ~PID_STOPPED;
1162 /* Clear pending stop signals */
1163 sig_clear (SIGSTOP);
1164 sig_clear (SIGTSTP);
1165 sig_clear (SIGTTIN);
1166 sig_clear (SIGTTOU);
1169 switch (si.si_signo)
1176 cygheap->ctty->sigflush ();
1184 sigproc_printf ("signal %d processing", si.si_signo);
1185 struct sigaction& thissig = global_sigs[si.si_signo];
1187 myself->rusage_self.ru_nsignals++;
1191 if (!have_execed || (void *) thissig.sa_handler == (void *) SIG_IGN)
1192 handler = (void *) thissig.sa_handler;
1198 _cygtls *use_tls = tls ?: _main_tls;
1200 if (si.si_signo == SIGKILL)
1202 if (si.si_signo == SIGSTOP)
1204 sig_clear (SIGCONT);
1208 bool insigwait_mask;
1209 if ((masked = ISSTATE (myself, PID_STOPPED)))
1210 insigwait_mask = false;
1212 insigwait_mask = sigismember (&tls->sigwait_mask, si.si_signo);
1213 else if (!(tls = _cygtls::find_tls (si.si_signo)))
1214 insigwait_mask = false;
1218 insigwait_mask = true;
1222 goto thread_specific;
1225 /* nothing to do */;
1226 else if (sigismember (mask, si.si_signo))
1229 masked = sigismember (&tls->sigmask, si.si_signo);
1233 sigproc_printf ("signal %d blocked", si.si_signo);
1238 /* Clear pending SIGCONT on stop signals */
1239 if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
1240 sig_clear (SIGCONT);
1243 if (being_debugged ())
1245 char sigmsg[sizeof (_CYGWIN_SIGNAL_STRING " 0xffffffff")];
1246 __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %p", si.si_signo);
1247 OutputDebugString (sigmsg);
1251 if (handler == (void *) SIG_DFL)
1254 goto thread_specific;
1255 if (si.si_signo == SIGCHLD || si.si_signo == SIGIO || si.si_signo == SIGCONT || si.si_signo == SIGWINCH
1256 || si.si_signo == SIGURG)
1258 sigproc_printf ("default signal %d ignored", si.si_signo);
1260 SetEvent (signal_arrived);
1264 if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
1270 if (handler == (void *) SIG_IGN)
1272 sigproc_printf ("signal %d ignored", si.si_signo);
1276 if (handler == (void *) SIG_ERR)
1279 use_tls->set_siginfo (this);
1283 /* Eat multiple attempts to STOP */
1284 if (ISSTATE (myself, PID_STOPPED))
1286 handler = (void *) sig_handle_tty_stop;
1290 /* Dispatch to the appropriate function. */
1291 sigproc_printf ("signal %d, about to call %p", si.si_signo, handler);
1292 rc = setup_handler (si.si_signo, handler, thissig, use_tls);
1298 sigproc_printf ("returning %d", rc);
1302 use_tls->sig = si.si_signo;
1303 use_tls->set_siginfo (this);
1304 use_tls->func = NULL;
1305 sigproc_printf ("releasing sigwait for thread");
1306 SetEvent (use_tls->event);
1310 use_tls->signal_exit (si.si_signo); /* never returns */
1316 mask_sync.init ("mask_sync");
1326 _cygtls::call_signal_handler ()
1328 int this_sa_flags = 0;
1329 /* Call signal handler. */
1333 this_sa_flags = sa_flags;
1335 void (*thisfunc) (int) = func;
1338 reset_signal_arrived ();
1339 sigset_t this_oldmask = set_process_mask_delta ();
1340 int this_errno = saved_errno;
1342 unlock (); // make sure synchronized
1344 if (!(this_sa_flags & SA_SIGINFO))
1346 void (*sigfunc) (int) = thisfunc;
1351 siginfo_t thissi = infodata;
1352 void (*sigact) (int, siginfo_t *, void *) = (void (*) (int, siginfo_t *, void *)) thisfunc;
1353 /* no ucontext_t information provided yet */
1354 sigact (thissig, &thissi, NULL);
1357 set_signal_mask (this_oldmask, _my_tls.sigmask);
1358 if (this_errno >= 0)
1359 set_errno (this_errno);
1362 return this_sa_flags & SA_RESTART;
1365 extern "C" void __stdcall
1366 reset_signal_arrived ()
1368 // NEEDED? WaitForSingleObject (signal_arrived, 10);
1369 ResetEvent (signal_arrived);
1370 sigproc_printf ("reset signal_arrived");
1371 if (_my_tls.stackptr > _my_tls.stack)
1372 debug_printf ("stackptr[-1] %p", _my_tls.stackptr[-1]);
1376 _cygtls::copy_context (CONTEXT *c)
1378 memcpy (&thread_context, c, (&thread_context._internal - (unsigned char *) &thread_context));
1382 _cygtls::signal_debugger (int sig)
1384 if (isinitialized () && being_debugged ())
1386 char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING " ffffffff ffffffff")];
1387 __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %d %p %p", sig, thread_id, &thread_context);
1388 OutputDebugString (sigmsg);